Browse Source

Aug 17: [ADD] Initital Commits 'certificate_license_expiry'

pull/254/merge
Cybrosys Technologies 8 months ago
parent
commit
6ea9a2451d
  1. 49
      certificate_license_expiry/README.rst
  2. 23
      certificate_license_expiry/__init__.py
  3. 77
      certificate_license_expiry/__manifest__.py
  4. 27
      certificate_license_expiry/controllers/__init__.py
  5. 74
      certificate_license_expiry/controllers/certificates.py
  6. 79
      certificate_license_expiry/controllers/certificates_group_by.py
  7. 48
      certificate_license_expiry/controllers/certificates_search.py
  8. 72
      certificate_license_expiry/controllers/license.py
  9. 77
      certificate_license_expiry/controllers/license_group_by.py
  10. 46
      certificate_license_expiry/controllers/license_search.py
  11. 123
      certificate_license_expiry/data/certificates_mail_template_data.xml
  12. 27
      certificate_license_expiry/data/ir_cron_data.xml
  13. 27
      certificate_license_expiry/data/ir_sequence_data.xml
  14. 123
      certificate_license_expiry/data/license_mail_template_data.xml
  15. 45
      certificate_license_expiry/demo/certificates_license_tags_demo.xml
  16. 53
      certificate_license_expiry/demo/certificates_license_types_demo.xml
  17. 7
      certificate_license_expiry/doc/RELEASE_NOTES.md
  18. 24
      certificate_license_expiry/models/__init__.py
  19. 212
      certificate_license_expiry/models/certificates.py
  20. 191
      certificate_license_expiry/models/license.py
  21. 70
      certificate_license_expiry/models/res_partner.py
  22. 25
      certificate_license_expiry/report/certificates_reports.xml
  23. 150
      certificate_license_expiry/report/certificates_templates.xml
  24. 24
      certificate_license_expiry/report/license_reports.xml
  25. 150
      certificate_license_expiry/report/license_templates.xml
  26. 29
      certificate_license_expiry/security/certificates_license_expiry_groups.xml
  27. 30
      certificate_license_expiry/security/certificates_security.xml
  28. 13
      certificate_license_expiry/security/ir.model.access.csv
  29. 30
      certificate_license_expiry/security/license_security.xml
  30. BIN
      certificate_license_expiry/static/description/assets/icons/check.png
  31. BIN
      certificate_license_expiry/static/description/assets/icons/chevron.png
  32. BIN
      certificate_license_expiry/static/description/assets/icons/cogs.png
  33. BIN
      certificate_license_expiry/static/description/assets/icons/consultation.png
  34. BIN
      certificate_license_expiry/static/description/assets/icons/ecom-black.png
  35. BIN
      certificate_license_expiry/static/description/assets/icons/education-black.png
  36. BIN
      certificate_license_expiry/static/description/assets/icons/hotel-black.png
  37. BIN
      certificate_license_expiry/static/description/assets/icons/license.png
  38. BIN
      certificate_license_expiry/static/description/assets/icons/lifebuoy.png
  39. BIN
      certificate_license_expiry/static/description/assets/icons/manufacturing-black.png
  40. BIN
      certificate_license_expiry/static/description/assets/icons/pos-black.png
  41. BIN
      certificate_license_expiry/static/description/assets/icons/puzzle.png
  42. BIN
      certificate_license_expiry/static/description/assets/icons/restaurant-black.png
  43. BIN
      certificate_license_expiry/static/description/assets/icons/service-black.png
  44. BIN
      certificate_license_expiry/static/description/assets/icons/trading-black.png
  45. BIN
      certificate_license_expiry/static/description/assets/icons/training.png
  46. BIN
      certificate_license_expiry/static/description/assets/icons/update.png
  47. BIN
      certificate_license_expiry/static/description/assets/icons/user.png
  48. BIN
      certificate_license_expiry/static/description/assets/icons/wrench.png
  49. BIN
      certificate_license_expiry/static/description/assets/misc/categories.png
  50. BIN
      certificate_license_expiry/static/description/assets/misc/check-box.png
  51. BIN
      certificate_license_expiry/static/description/assets/misc/compass.png
  52. BIN
      certificate_license_expiry/static/description/assets/misc/corporate.png
  53. BIN
      certificate_license_expiry/static/description/assets/misc/customer-support.png
  54. BIN
      certificate_license_expiry/static/description/assets/misc/cybrosys-logo.png
  55. BIN
      certificate_license_expiry/static/description/assets/misc/features.png
  56. BIN
      certificate_license_expiry/static/description/assets/misc/logo.png
  57. BIN
      certificate_license_expiry/static/description/assets/misc/pictures.png
  58. BIN
      certificate_license_expiry/static/description/assets/misc/pie-chart.png
  59. BIN
      certificate_license_expiry/static/description/assets/misc/right-arrow.png
  60. BIN
      certificate_license_expiry/static/description/assets/misc/star.png
  61. BIN
      certificate_license_expiry/static/description/assets/misc/support.png
  62. BIN
      certificate_license_expiry/static/description/assets/misc/whatsapp.png
  63. BIN
      certificate_license_expiry/static/description/assets/modules/1.png
  64. BIN
      certificate_license_expiry/static/description/assets/modules/2.png
  65. BIN
      certificate_license_expiry/static/description/assets/modules/3.png
  66. BIN
      certificate_license_expiry/static/description/assets/modules/4.png
  67. BIN
      certificate_license_expiry/static/description/assets/modules/5.png
  68. BIN
      certificate_license_expiry/static/description/assets/modules/6.png
  69. BIN
      certificate_license_expiry/static/description/assets/screenshots/Certificate Report.pdf
  70. BIN
      certificate_license_expiry/static/description/assets/screenshots/active-certificate-tree-view.png
  71. BIN
      certificate_license_expiry/static/description/assets/screenshots/active-certificate.png
  72. BIN
      certificate_license_expiry/static/description/assets/screenshots/active-license-tree-view.png
  73. BIN
      certificate_license_expiry/static/description/assets/screenshots/active-license.png
  74. BIN
      certificate_license_expiry/static/description/assets/screenshots/certificate-expire-reminder-day.png
  75. BIN
      certificate_license_expiry/static/description/assets/screenshots/certificate-expired-mail-template.png
  76. BIN
      certificate_license_expiry/static/description/assets/screenshots/certificate-expiry-notification.png
  77. BIN
      certificate_license_expiry/static/description/assets/screenshots/certificate-group-sort.png
  78. BIN
      certificate_license_expiry/static/description/assets/screenshots/certificate-group-tags.png
  79. BIN
      certificate_license_expiry/static/description/assets/screenshots/certificate-group-type.png
  80. BIN
      certificate_license_expiry/static/description/assets/screenshots/certificate-kanban-view.png
  81. BIN
      certificate_license_expiry/static/description/assets/screenshots/certificate-license-customer-view.png
  82. BIN
      certificate_license_expiry/static/description/assets/screenshots/certificate-license-customer.png
  83. BIN
      certificate_license_expiry/static/description/assets/screenshots/certificate-license-manager.png
  84. BIN
      certificate_license_expiry/static/description/assets/screenshots/certificate-pdf-report-button.png
  85. BIN
      certificate_license_expiry/static/description/assets/screenshots/certificate-pdf-report.png
  86. BIN
      certificate_license_expiry/static/description/assets/screenshots/certificate-portal-form.png
  87. BIN
      certificate_license_expiry/static/description/assets/screenshots/certificate-portal-search.png
  88. BIN
      certificate_license_expiry/static/description/assets/screenshots/certificate-portal-tree.png
  89. BIN
      certificate_license_expiry/static/description/assets/screenshots/certificates-calendar-view.png
  90. BIN
      certificate_license_expiry/static/description/assets/screenshots/certificates-form-view.png
  91. BIN
      certificate_license_expiry/static/description/assets/screenshots/certificates-graph-view.png
  92. BIN
      certificate_license_expiry/static/description/assets/screenshots/certificates-licenses-submenu.png
  93. BIN
      certificate_license_expiry/static/description/assets/screenshots/certificates-tree-view.png
  94. BIN
      certificate_license_expiry/static/description/assets/screenshots/configuration-sub-menu.png
  95. BIN
      certificate_license_expiry/static/description/assets/screenshots/contact-certificates.png
  96. BIN
      certificate_license_expiry/static/description/assets/screenshots/contact-licenses.png
  97. BIN
      certificate_license_expiry/static/description/assets/screenshots/contact-smart-button.png
  98. BIN
      certificate_license_expiry/static/description/assets/screenshots/hero.gif
  99. BIN
      certificate_license_expiry/static/description/assets/screenshots/license-calendar-view.png
  100. BIN
      certificate_license_expiry/static/description/assets/screenshots/license-expire-reminder-day.png

49
certificate_license_expiry/README.rst

@ -0,0 +1,49 @@
.. image:: https://img.shields.io/badge/license-LGPL--3-blue.svg
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
:alt: License: LGPL-3
Certificate And License With Expiry Management
==============================================
This module allow to manage certificates and licenses.
Configuration
=============
* No configuration is required
License
=======
Lesser General Public License v3.0 (LGPL v3)
(http://www.gnu.org/licenses/lgpl-3.0-standalone.html)
Company
-------
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__
Credits
-------
* Developer:
(V15) Ranjith R,
(V16) Albin P J,
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>`__

23
certificate_license_expiry/__init__.py

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Ranjith R (odoo@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 controllers
from . import models

77
certificate_license_expiry/__manifest__.py

@ -0,0 +1,77 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Ranjith R (odoo@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': 'Certificate And License With Expiry Management',
'version': '15.0.1.0.0',
'category': 'Document Management',
'summary': """Certificate And License With Expiry Management helps you
to manage certificates and licenses""",
'description': """We can manage the certificates and licenses
using this module""",
'author': 'Cybrosys Techno Solutions',
'company': 'Cybrosys Techno Solutions',
'maintainer': 'Cybrosys Techno Solutions',
'website': "https://www.cybrosys.com",
'depends': ['project', 'contacts', 'website', 'product'],
'data': [
'security/certificates_license_expiry_groups.xml',
'security/certificates_security.xml',
'security/license_security.xml',
'security/ir.model.access.csv',
'data/ir_sequence_data.xml',
'data/ir_cron_data.xml',
'data/certificates_mail_template_data.xml',
'data/license_mail_template_data.xml',
'views/certificates_license_menus.xml',
'views/certificates_views.xml',
'views/license_views.xml',
'views/certificates_portal.xml',
'views/res_partner_views.xml',
'views/license_portal.xml',
'views/certificates_search.xml',
'views/license_search.xml',
'report/certificates_reports.xml',
'report/license_reports.xml',
'report/certificates_templates.xml',
'report/license_templates.xml',
],
'demo': [
'demo/certificates_license_types_demo.xml',
'demo/certificates_license_tags_demo.xml',
],
'assets': {
'web.assets_backend': [
'certificate_license_expiry/static/src/css/certificate_license.css',
],
'web.assets_frontend': [
'certificate_license_expiry/static/src/js/certificates_group_by.js',
'certificate_license_expiry/static/src/js/certificates_search.js',
'certificate_license_expiry/static/src/js/license_group_by.js',
'certificate_license_expiry/static/src/js/license_search.js',
],
},
'images': ['static/description/banner.png'],
'license': 'LGPL-3',
'installable': True,
'auto_install': False,
'application': True,
}

27
certificate_license_expiry/controllers/__init__.py

@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Ranjith R (odoo@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 certificates
from . import certificates_group_by
from . import certificates_search
from . import license
from . import license_group_by
from . import license_search

74
certificate_license_expiry/controllers/certificates.py

@ -0,0 +1,74 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Ranjith R (odoo@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 http
from odoo.http import request
from odoo.addons.portal.controllers import portal
class MyCertificates(http.Controller):
"""It returns the login person"""
def _get_tickets_domain(self):
"""It returns the login person"""
return [('customer_id', '=', request.env.user.partner_id.id)]
@http.route(['/my/certificates'], type='http', auth="user", website=True)
def get_my_certificates(self):
"""Take values from certificates and render to portal tree template """
domain = self._get_tickets_domain()
certificates = request.env['certificates'].sudo().search(domain)
values = {
'certificates': certificates,
'page_name': 'certificate',
}
return request.render(
"certificate_license_expiry.portal_my_certificates", values)
@http.route(['/my/certificates/form/<int:cer_id>'], type='http',
auth="user", website=True)
def get_my_certificates_form(self, cer_id):
"""Take values from certificates and render to portal form
template.It also passes the id in the root for rendering the
corresponding form template"""
certificates = request.env['certificates'].sudo().search(
[('id', '=', cer_id)])
values = {
'my_certificates': certificates,
'page_name': 'certificate_view',
}
return request.render(
"certificate_license_expiry.certificates_portal_form_template",
values)
class Return(portal.CustomerPortal):
"""This will take the count of total certificates"""
def _prepare_home_portal_values(self, counters):
"""This will return the certificates count"""
values = super(Return, self)._prepare_home_portal_values(counters)
certificates = request.env['certificates'].sudo().search_count(
[('customer_id', '=', request.env.user.partner_id.id)])
values.update({
'certificates': certificates
})
return values

79
certificate_license_expiry/controllers/certificates_group_by.py

@ -0,0 +1,79 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Ranjith R (odoo@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 http
from odoo.http import request
class CertificatesGroupBy(http.Controller):
"""This is used to certificates group by in tree view"""
@http.route(['/certificatesgroupby'], type='json', auth="public",
website=True)
def certificates_group_by(self, **kwargs):
"""Call from rpc for group by, and it returns the corresponding
values"""
context = []
group_value = kwargs.get("search_value")
if group_value == '0':
certificates = request.env["certificates"].sudo().search(
[('customer_id', '=', request.env.user.partner_id.id)])
values = {
'certificates': certificates,
}
response = http.Response(
template='certificate_license_expiry.portal_my_certificates_tree',
qcontext=values)
return response.render()
if group_value == '1':
context = []
type_ids = request.env['certificates.types'].sudo().search([])
for types in type_ids:
certificates_ids = request.env['certificates'].sudo().search([
('certificates_types_id', '=', types.id),
('customer_id', '=', request.env.user.partner_id.id)
])
if certificates_ids:
context.append({
'name': types.certificate_type,
'data': certificates_ids
})
if group_value == '2':
context = []
tag_ids = request.env['certificates.tags'].sudo().search([])
for tags in tag_ids:
certificates_ids = request.env['certificates'].sudo().search([
('certificates_tags_ids', '=', tags.id),
('customer_id', '=', request.env.user.partner_id.id)
])
if certificates_ids:
context.append({
'name': tags.certificates_tags,
'data': certificates_ids
})
values = {
'certificates': context,
}
response = http.Response(
template='certificate_license_expiry'
'.certificates_group_by_template',
qcontext=values)
return response.render()

48
certificate_license_expiry/controllers/certificates_search.py

@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Ranjith R (odoo@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 http
from odoo.http import request
class MyCertificatesSearch(http.Controller):
"""This is used to search feature in certificates portal tree view"""
@http.route(['/certificatesearch'], type='json', auth="public",
website=True)
def certificates_search(self, **kwargs):
"""It gives the values and return the response to corresponding
template"""
search_value = kwargs.get("search_value")
if not search_value:
certificates = request.env["certificates"].sudo().search(
[('customer_id', '=', request.env.user.partner_id.id)])
else:
certificates = request.env["certificates"].sudo().search(
[('certificate_number', 'ilike', search_value),
('customer_id', '=', request.env.user.partner_id.id)])
values = {
'certificates': certificates,
}
response = http.Response(
template='certificate_license_expiry.portal_my_certificates_tree',
qcontext=values)
return response.render()

72
certificate_license_expiry/controllers/license.py

@ -0,0 +1,72 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Ranjith R (odoo@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 http
from odoo.http import request
from odoo.addons.portal.controllers import portal
class MyLicense(http.Controller):
"""It returns the login person"""
def _get_tickets_domain(self):
"""It returns the login person"""
return [('customer_id', '=', request.env.user.partner_id.id)]
@http.route(['/my/license'], type='http', auth="user", website=True)
def get_my_license(self):
"""Take values from licenses and render to portal tree template """
domain = self._get_tickets_domain()
license = request.env['license'].sudo().search(domain)
values = {'license': license,
'page_name': 'license',
}
return request.render(
"certificate_license_expiry.portal_my_license", values)
@http.route(['/my/license/form/<int:lic_id>'], type='http', auth="user",
website=True)
def get_my_license_form(self, lic_id):
"""Take values from license and render to portal form template.It
also passes the id in the root for rendering the corresponding form
template"""
license = request.env['license'].sudo().search([('id', '=', lic_id)])
values = {
'my_license': license,
'page_name': 'license_view',
}
return request.render(
"certificate_license_expiry.license_portal_form_template",
values)
class Return(portal.CustomerPortal):
"""This will take the count of total license"""
def _prepare_home_portal_values(self, counters):
"""This will return the license count"""
values = super(Return, self)._prepare_home_portal_values(counters)
license = request.env['license'].sudo().search_count(
[('customer_id', '=', request.env.user.partner_id.id)])
values.update({
'license': license
})
return values

77
certificate_license_expiry/controllers/license_group_by.py

@ -0,0 +1,77 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Ranjith R (odoo@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 http
from odoo.http import request
class LicenseGroupBy(http.Controller):
"""This is used to license group by in tree view"""
@http.route(['/licensegroupby'], type='json', auth="public", website=True)
def license_group_by(self, **kwargs):
"""Call from rpc for group by, and it returns the corresponding
values"""
context = []
group_value = kwargs.get("search_value")
if group_value == '0':
license = request.env["license"].sudo().search(
[('customer_id', '=', request.env.user.partner_id.id)])
values = {
'license': license,
}
response = http.Response(
template='certificate_license_expiry.portal_my_license_tree',
qcontext=values)
return response.render()
if group_value == '1':
context = []
type_ids = request.env['license.types'].sudo().search([])
for types in type_ids:
license_ids = request.env['license'].sudo().search([
('license_types_id', '=', types.id),
('customer_id', '=', request.env.user.partner_id.id)
])
if license_ids:
context.append({
'name': types.license_type,
'data': license_ids
})
if group_value == '2':
context = []
tag_ids = request.env['license.tags'].sudo().search([])
for tags in tag_ids:
license_ids = request.env['license'].sudo().search([
('license_tags_ids', '=', tags.id),
('customer_id', '=', request.env.user.partner_id.id)
])
if license_ids:
context.append({
'name': tags.license_tags_ids,
'data': license_ids
})
values = {
'license': context,
}
response = http.Response(
template='certificate_license_expiry.license_group_by_template',
qcontext=values)
return response.render()

46
certificate_license_expiry/controllers/license_search.py

@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Ranjith R (odoo@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 http
from odoo.http import request
class MyLicenseSearch(http.Controller):
"""This is used to search feature in license portal tree view"""
@http.route(['/licensesearch'], type='json', auth="public", website=True)
def license_search(self, **kwargs):
"""It gives the values and return the response to corresponding
template"""
search_value = kwargs.get("search_value")
license = request.env["license"].sudo().search(
[('customer_id', '=',
request.env.user.partner_id.id)]) if not search_value else \
request.env["license"].sudo().search(
[('license_number', 'ilike', search_value),
('customer_id', '=', request.env.user.partner_id.id)])
values = {
'license': license,
}
response = http.Response(
template='certificate_license_expiry.portal_my_license_tree',
qcontext=values)
return response.render()

123
certificate_license_expiry/data/certificates_mail_template_data.xml

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!--Mail Template to send when the certificate is expired-->
<record id="email_template_certificate" model="mail.template">
<field name="name">Certificate Expiry Mail</field>
<field name="model_id" ref="model_certificates"/>
<field name="subject">Certificate Expiry</field>
<field name="body_html" type="html">
<div style="margin: 0px; padding: 0px;">
<p style="margin: 0px; padding: 0px; font-size: 13px;">
<strong>Hello,
<br/>
</strong>
<strong>
<span t-esc="object.customer_id.name"/>
Your Certificate Is Expired
</strong>
</p>
</div>
<br/>
<table width="100%"
style="color: #454748; font-size: 12px; border-collapse: collapse;">
<tr style="border-bottom: 1px solid #636363;">
<td style="width: 150px;">
<h2>
<t t-esc="object.certificate_number"/>
</h2>
</td>
</tr>
<tr style="border-bottom: 1px solid #636363;">
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>Certificate</strong>
</td>
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>
<t t-esc="object.name"/>
</strong>
</td>
</tr>
<tr style="border-bottom: 1px solid #636363;">
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>Start Date</strong>
</td>
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>
<t t-esc="object.start_date"/>
</strong>
</td>
</tr>
<tr style="border-bottom: 1px solid #636363;">
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>Expire Date</strong>
</td>
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>
<t t-esc="object.expire_date"/>
</strong>
</td>
</tr>
<tr style="border-bottom: 1px solid #636363;">
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>Certificate Type</strong>
</td>
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>
<t t-esc="object.certificates_types_id.certificate_type"/>
</strong>
</td>
</tr>
<tr style="border-bottom: 1px solid #636363;">
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>Issued by</strong>
</td>
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>
<t t-esc="object.issued_company_id.name"/>
</strong>
</td>
</tr>
<tr style="border-bottom: 1px solid #636363;">
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>Project</strong>
</td>
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>
<t t-esc="object.project_id.name"/>
</strong>
</td>
</tr>
<tr style="border-bottom: 1px solid #636363;">
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>Task</strong>
</td>
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>
<t t-esc="object.task_id.name"/>
</strong>
</td>
</tr>
<tr style="border-bottom: 1px solid #636363;">
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>Product</strong>
</td>
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>
<t t-esc="object.product_id.name"/>
</strong>
</td>
</tr>
<tr style="border-bottom: 1px solid #636363;">
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>Status</strong>
</td>
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>
<t t-esc="object.state"/>
</strong>
</td>
</tr>
</table>
</field>
</record>
</odoo>

27
certificate_license_expiry/data/ir_cron_data.xml

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!--Scheduled action to check whether the Certificate is expired or not-->
<record id="certificate_expiry_action" model="ir.cron">
<field name="name">Certificate Expiry</field>
<field name="model_id" ref="model_certificates"/>
<field name="state">code</field>
<field name="code">model.certificate_expiry_action()</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>
<field name="doall" eval="False"/>
</record>
<!--Scheduled action to check whether the License is expired or not-->
<record id="license_expiry_action" model="ir.cron">
<field name="name">License Expiry</field>
<field name="model_id" ref="model_license"/>
<field name="state">code</field>
<field name="code">model.license_expiry_action()</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>
<field name="doall" eval="False"/>
</record>
</odoo>

27
certificate_license_expiry/data/ir_sequence_data.xml

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<!--Sequence Code of the Certificates-->
<record id="sequence_certificate" model="ir.sequence">
<field name="name">Certificate</field>
<field name="code">certificates</field>
<field name="active">True</field>
<field name="prefix">CER</field>
<field name="padding">5</field>
<field name="number_next">1</field>
<field name="number_increment">1</field>
<field name="company_id" eval="False"/>
</record>
<!--Sequence Code of the Licenses-->
<record id="sequence_license" model="ir.sequence">
<field name="name">License</field>
<field name="code">license</field>
<field name="active">True</field>
<field name="prefix">LIC</field>
<field name="padding">5</field>
<field name="number_next">1</field>
<field name="number_increment">1</field>
<field name="company_id" eval="False"/>
</record>
</data>
</odoo>

123
certificate_license_expiry/data/license_mail_template_data.xml

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!--Mail Template to send when the license is expired-->
<record id="email_template_license" model="mail.template">
<field name="name">License Expiry Mail</field>
<field name="model_id" ref="model_license"/>
<field name="subject">License Expiry</field>
<field name="body_html" type="html">
<div style="margin: 0px; padding: 0px;">
<p style="margin: 0px; padding: 0px; font-size: 13px;">
<strong>Hello,
<br/>
</strong>
<strong>
<span t-esc="object.customer_id.name"/>
Your License Is Expired
</strong>
</p>
</div>
<br/>
<table width="100%"
style="color: #454748; font-size: 12px; border-collapse: collapse;">
<tr style="border-bottom: 1px solid #636363;">
<td style="width: 150px;">
<h2>
<t t-esc="object.license_number"/>
</h2>
</td>
</tr>
<tr style="border-bottom: 1px solid #636363;">
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>License</strong>
</td>
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>
<t t-esc="object.name"/>
</strong>
</td>
</tr>
<tr style="border-bottom: 1px solid #636363;">
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>Start Date</strong>
</td>
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>
<t t-esc="object.start_date"/>
</strong>
</td>
</tr>
<tr style="border-bottom: 1px solid #636363;">
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>Expire Date</strong>
</td>
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>
<t t-esc="object.expire_date"/>
</strong>
</td>
</tr>
<tr style="border-bottom: 1px solid #636363;">
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>License Type</strong>
</td>
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>
<t t-esc="object.license_types_id.license_type"/>
</strong>
</td>
</tr>
<tr style="border-bottom: 1px solid #636363;">
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>Issued by</strong>
</td>
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>
<t t-esc="object.issued_company_id.name"/>
</strong>
</td>
</tr>
<tr style="border-bottom: 1px solid #636363;">
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>Project</strong>
</td>
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>
<t t-esc="object.project_id.name"/>
</strong>
</td>
</tr>
<tr style="border-bottom: 1px solid #636363;">
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>Task</strong>
</td>
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>
<t t-esc="object.task_id.name"/>
</strong>
</td>
</tr>
<tr style="border-bottom: 1px solid #636363;">
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>Product</strong>
</td>
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>
<t t-esc="object.product_id.name"/>
</strong>
</td>
</tr>
<tr style="border-bottom: 1px solid #636363;">
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>Status</strong>
</td>
<td style="width: 150px;border-right: 1px solid #636363;border-left: 1px solid #636363;">
<strong>
<t t-esc="object.state"/>
</strong>
</td>
</tr>
</table>
</field>
</record>
</odoo>

45
certificate_license_expiry/demo/certificates_license_tags_demo.xml

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<!--Demo Data to create in model certificate.tags-->
<record id="certificate_tag_1" model="certificates.tags">
<field name="certificates_tags">New</field>
</record>
<!--Demo Data to create in model certificate.tags-->
<record id="certificate_tag_2" model="certificates.tags">
<field name="certificates_tags">Old</field>
</record>
<!--Demo Data to create in model certificate.tags-->
<record id="certificate_tag_3" model="certificates.tags">
<field name="certificates_tags">Information</field>
</record>
<!--Demo Data to create in model certificate.tags-->
<record id="certificate_tag_4" model="certificates.tags">
<field name="certificates_tags">Online</field>
</record>
<!--Demo Data to create in model certificate.tags-->
<record id="certificate_tag_5" model="certificates.tags">
<field name="certificates_tags">Others</field>
</record>
<!--Demo Data to create in model license.tags-->
<record id="license_tag_1" model="license.tags">
<field name="license_tags_ids">New</field>
</record>
<!--Demo Data to create in model license.tags-->
<record id="license_tag_2" model="license.tags">
<field name="license_tags_ids">Old</field>
</record>
<!--Demo Data to create in model license.tags-->
<record id="license_tag_3" model="license.tags">
<field name="license_tags_ids">Information</field>
</record>
<!--Demo Data to create in model license.tags-->
<record id="license_tag_4" model="license.tags">
<field name="license_tags_ids">Online</field>
</record>
<!--Demo Data to create in model license.tags-->
<record id="license_tag_5" model="license.tags">
<field name="license_tags_ids">Other</field>
</record>
</data>
</odoo>

53
certificate_license_expiry/demo/certificates_license_types_demo.xml

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<!--Demo Data to create in model certificates.types-->
<record id="certificate_type_1" model="certificates.types">
<field name="certificate_type">Personal</field>
</record>
<!--Demo Data to create in model certificates.types-->
<record id="certificate_type_2" model="certificates.types">
<field name="certificate_type">Professional</field>
</record>
<!--Demo Data to create in model certificates.types-->
<record id="certificate_type_3" model="certificates.types">
<field name="certificate_type">Experience</field>
</record>
<!--Demo Data to create in model certificates.types-->
<record id="certificate_type_4" model="certificates.types">
<field name="certificate_type">Birth</field>
</record>
<!--Demo Data to create in model certificates.types-->
<record id="certificate_type_5" model="certificates.types">
<field name="certificate_type">Degree</field>
</record>
<!--Demo Data to create in model certificates.types-->
<record id="certificate_type_6" model="certificates.types">
<field name="certificate_type">Business</field>
</record>
<!--Demo Data to create in model license.types-->
<record id="license_type_1" model="license.types">
<field name="license_type">Personal</field>
</record>
<!--Demo Data to create in model license.types-->
<record id="license_type_2" model="license.types">
<field name="license_type">Professional</field>
</record>
<!--Demo Data to create in model license.types-->
<record id="license_type_3" model="license.types">
<field name="license_type">Operating</field>
</record>
<!--Demo Data to create in model license.types-->
<record id="license_type_4" model="license.types">
<field name="license_type">Premises</field>
</record>
<!--Demo Data to create in model license.types-->
<record id="license_type_5" model="license.types">
<field name="license_type">Course</field>
</record>
<!--Demo Data to create in model license.types-->
<record id="license_type_6" model="license.types">
<field name="license_type">Business</field>
</record>
</data>
</odoo>

7
certificate_license_expiry/doc/RELEASE_NOTES.md

@ -0,0 +1,7 @@
## Module <certificate_license_expiry>
#### 22.07.2024
#### Version 15.0.1.0.0
#### ADD
- Initial commit for Certificate And License With Expiry Management

24
certificate_license_expiry/models/__init__.py

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Ranjith R (odoo@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 certificates
from . import license
from . import res_partner

212
certificate_license_expiry/models/certificates.py

@ -0,0 +1,212 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Ranjith R (odoo@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 random import randint
from odoo import api, fields, models, _
from odoo.exceptions import ValidationError
class Certificates(models.Model):
"""This will give all about certificates such as fields etc"""
_name = 'certificates'
_description = "Certificates"
_inherit = ["mail.thread", "mail.activity.mixin"]
state = fields.Selection(
selection=[('new', 'New'), ('active', 'Active'),
('expired_soon', 'Expiring Soon'), ('expired', 'Expired')],
string="State", default='new', help="Sates of certificate")
name = fields.Char(string='Name', required=True, help="Name of certificate")
certificate_number = fields.Char(string="Certificate Number",
readonly=True, copy=False,
default='New', help="Sequence number")
customer_id = fields.Many2one('res.partner', string="Customer",
required=True, help="Name of the customer")
certificates_types_id = fields.Many2one('certificates.types',
string="Certificates Types",
required=True, help="Type of the "
"certificate")
start_date = fields.Date(string="Start Date", required=True,
default=fields.Date.today(), help="Certificate "
"start date")
expire_date = fields.Date(string="Expire Date", help="Certificate expiry "
"date")
issued_company_id = fields.Many2one('res.company', string="Issued By",
required=True,
help="Certificate issued by "
"which company")
certificates_tags_ids = fields.Many2many('certificates.tags', string="Tags",
help="Tags of the certificate")
project_id = fields.Many2one('project.project', string="Project",
required=True,
help="Project corresponding to the "
"certificate")
task_id = fields.Many2one('project.task', string="Task",
domain="[('project_id', '=', project_id)]",
required=True,
help="Task corresponding to the certificate")
product_id = fields.Many2one('product.product', string="Product",
required=True,
help="Product corresponding to the "
"certificate")
user_id = fields.Many2one('res.users', string="Responsible Person",
required=True,
default=lambda self: self.env.user,
help="Responsible user of the certificate")
company_id = fields.Many2one('res.company', string="Company",
default=lambda self: self.env.company,
readonly=True,
help="Company corresponding to the "
"certificate")
expire_remainder_day = fields.Integer(string="Expire Reminder Day",
help="Certificate expire remainder "
"day")
login_user_id = fields.Many2one('res.users', string='Login User',
default=lambda self: self.env.user,
readonly=True,
help="ID of the logged in user")
internal_notes = fields.Text(string="Internal Notes",
help="Internal notes of the certificate")
description = fields.Text(string="Description", required=True,
help="Description of the certificate")
achievements = fields.Text(string="Achievements",
help="Achievements in the certificate")
has_expired = fields.Boolean(string="Expired Certificate",
help="Becomes True if the certificate "
"has expired")
@api.model
def create(self, vals):
"""This is used to get the certificate number"""
if vals.get('certificate_number', 'New') == 'New':
vals['certificate_number'] = self.env['ir.sequence'].next_by_code(
'certificates') or 'New'
result = super(Certificates, self).create(vals)
return result
@api.constrains('start_date', 'expire_date')
def _constrains_certificate_start_date_expire_date(self):
"""This will give validation at the time of expired date and start
date have any problem"""
if self.start_date and self.expire_date:
if (self.start_date > self.expire_date or fields.Date.today() >
self.expire_date):
raise ValidationError(_('Expire Date Is Not Valid'))
def active_certificate(self):
"""It changes the state into active"""
self.state = 'active'
def action_active_certificate(self):
"""It returns the certificate tree view"""
return {
'name': 'Active',
'view_mode': 'tree',
'res_model': 'certificates',
'type': 'ir.actions.act_window',
'domain': [('state', '=', 'active')],
'context': "{'create': False}"
}
def certificate_expiry_action(self):
"""This function is from scheduled action, it will send mail
notification and change the state based on condition given below"""
certificates = self.env['certificates'].search(
[('has_expired', '=', False)])
today = fields.Date.today()
for rec in certificates:
if rec.expire_date and today >= fields.Date.subtract(
rec.expire_date, days=rec.expire_remainder_day):
rec.state = 'expired_soon'
if rec.expire_date and today >= rec.expire_date and rec.state != 'expired':
email_values = {
'email_cc': False,
'auto_delete': True,
'recipient_ids': [],
'partner_ids': [],
'scheduled_date': False,
'email_to': rec.customer_id.email
}
template = self.env.ref(
'certificate_license_expiry.email_template_certificate')
template.send_mail(rec.id, force_send=True,
email_values=email_values)
rec.state = 'expired'
rec.has_expired = True
def action_create_certificate_pdf_report(self):
"""This is used to get pdf report and passes the values to template"""
data = {
'record_name': self.name,
'record_certificate_number': self.certificate_number,
'record_customer_name': self.customer_id.name,
'record_certificate_type': self.certificates_types_id.certificate_type,
'record_start_date': self.start_date,
'record_expire_date': self.expire_date,
'record_issued_by': self.issued_company_id.name,
'record_project': self.project_id.name,
'record_task': self.task_id.name,
'record_user': self.user_id.name,
'record_company': self.company_id.name,
'record_internal_notes': self.internal_notes,
'record_description': self.description,
'record_achievements': self.achievements,
'record_expire_remainder_day': self.expire_remainder_day,
'record_product': self.product_id.name,
'record_state': self.state
}
return self.env.ref(
'certificate_license_expiry.action_certificate_report').report_action(
None, data=data)
class CertificatesType(models.Model):
"""This is certificates type model, it is a sub model of the
certificates"""
_name = 'certificates.types'
_description = "Certificates Type"
_rec_name = 'certificate_type'
certificate_type = fields.Char(string="Certificate Type", required=True,
help="Type of certificate")
_sql_constraints = [(
'certificate_type_unique', 'unique(certificate_type)',
'Already existing certificate type!')]
class CertificateTags(models.Model):
"""This is certificates tags model, it is a sub model of the
certificates"""
_name = 'certificates.tags'
_description = "Certificate Tag"
_rec_name = 'certificates_tags'
def _get_default_color(self):
"""This will give the colors to the corresponding field"""
return randint(1, 11)
certificates_tags = fields.Char(string="Certificate Tag", required=True,
help="Tags of certificate")
_sql_constraints = [(
'certificate_tag_unique', 'unique(certificates_tags)',
'Already existing certificate tag!')]
color = fields.Integer(string="Color", default=_get_default_color,
help="Color of tags")

191
certificate_license_expiry/models/license.py

@ -0,0 +1,191 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Ranjith R (odoo@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 random import randint
from odoo import api, fields, models, _
from odoo.exceptions import ValidationError
class License(models.Model):
"""This will give all about license such as fields etc"""
_name = 'license'
_description = "License"
_inherit = ["mail.thread", "mail.activity.mixin"]
state = fields.Selection(
selection=[('new', 'New'), ('active', 'Active'),
('expired_soon', 'Expiring Soon'), ('expired', 'Expired')],
string="State", default='new', help="Sates of certificate")
name = fields.Char(string='Name', required=True, help="Name of certificate")
license_number = fields.Char(string="Certificate Number", readonly=True,
copy=False, default='New',
help="Sequence number")
customer_id = fields.Many2one('res.partner', string="Customer",
required=True, help="Customer")
license_types_id = fields.Many2one('license.types',
string="License Types", required=True,
help="Type of the "
"license")
start_date = fields.Date(string="Start Date", required=True,
default=fields.Date.today(), help="License"
"start date")
expire_date = fields.Date(string="Expire Date", required=True,
default=fields.Date.today(),
help="License expiry "
"date")
issued_company_id = fields.Many2one('res.company', string="Issued By",
required=True, help="License issued by "
"which company")
license_tags_ids = fields.Many2many('license.tags', string="Tags",
help="Tags")
project_id = fields.Many2one('project.project', string="Project",
required=True, help="Project")
task_id = fields.Many2one('project.task', string="Task",
domain="[('project_id', '=', project_id)]",
required=True, help="Task")
product_id = fields.Many2one('product.product', string="Product",
required=True, help="Product")
user_id = fields.Many2one('res.users', string="Responsible Person",
required=True,
default=lambda self: self.env.user, help="User")
company_id = fields.Many2one('res.company', string="Company",
default=lambda self: self.env.company,
readonly=True, help="Company")
expire_remainder_day = fields.Integer(string="Expire Reminder Day",
help="License expire remainder"
"day")
login_user_id = fields.Many2one('res.users', string='Login User',
default=lambda self: self.env.user,
readonly=True, help="Login user")
internal_notes = fields.Text(string="Internal Notes", help="Internal notes")
description = fields.Text(string="Description", help="Description")
achievements = fields.Text(string="Achievements", help="Achievements")
has_expired = fields.Boolean(string="Expired License",
help="Becomes True if the License "
"has expired")
@api.model
def create(self, vals):
"""This is used to get the license number"""
if vals.get('license_number', 'New') == 'New':
vals['license_number'] = self.env['ir.sequence'].next_by_code(
'license') or 'New'
result = super(License, self).create(vals)
return result
@api.constrains('start_date', 'expire_date')
def _constrains_license_start_date_expire_date(self):
"""This will give validation at the time of expired date and start
date have any problem"""
if self.start_date and self.expire_date:
if self.start_date > self.expire_date or fields.Date.today() > self.expire_date:
raise ValidationError(_('Expire Date Is Not Valid'))
def active_license(self):
"""It changes the state into active"""
self.state = 'active'
def action_active_license(self):
"""It returns the license tree view"""
return {
'name': 'Active',
'view_mode': 'tree',
'res_model': 'license',
'type': 'ir.actions.act_window',
'domain': [('state', '=', 'active')],
'context': "{'create': False}"
}
def license_expiry_action(self):
"""This function is from scheduled action, it will send mail
notification and change the state based on condition given below"""
license = self.env['license'].search([('has_expired', '=', False)])
today = fields.Date.today()
for rec in license:
if today >= fields.Date.subtract(
rec.expire_date, days=rec.expire_remainder_day):
rec.state = 'expired_soon'
if today >= rec.expire_date and rec.state != 'expired':
email_values = {
'email_cc': False,
'auto_delete': True,
'recipient_ids': [],
'partner_ids': [],
'scheduled_date': False,
'email_to': rec.customer_id.email
}
template = self.env.ref(
'certificate_license_expiry.email_template_license')
template.send_mail(rec.id, force_send=True,
email_values=email_values)
rec.state = 'expired'
rec.has_expired = True
def action_create_license_pdf_report(self):
"""This is used to get pdf report and passes the values to template"""
data = {
'record_name': self.name,
'record_license_number': self.license_number,
'record_customer': self.customer_id.name,
'record_license_type': self.license_types_id.license_type,
'record_start_date': self.start_date,
'record_expire_date': self.expire_date,
'record_issued_by_': self.issued_company_id.name,
'record_project': self.project_id.name,
'record_task': self.task_id.name,
'record_user': self.user_id.name,
'record_company': self.company_id.name,
'record_internal_notes': self.internal_notes,
'record_description': self.description,
'record_achievements': self.achievements,
'record_expire_remainder_day': self.expire_remainder_day,
'record_product': self.product_id.name,
'record_state': self.state
}
return self.env.ref(
'certificate_license_expiry.action_license_report').report_action(
None, data=data)
class LicenseType(models.Model):
"""This is license type model, it is a sub model of the license """
_name = 'license.types'
_description = "License Type"
_rec_name = 'license_type'
license_type = fields.Char(string="License Type", required=True,
help="Type of license")
class LicenseTags(models.Model):
"""This is license tags model, it is a sub model of the license """
_name = 'license.tags'
_description = "License Tag"
_rec_name = 'license_tags_ids'
def _get_default_color(self):
"""This will give the colors to the corresponding field"""
return randint(1, 11)
license_tags_ids = fields.Char(string="License Tag", required=True,
help="Tags fpr license")
color = fields.Integer(string="Color", default=_get_default_color,
help="Color of tags")

70
certificate_license_expiry/models/res_partner.py

@ -0,0 +1,70 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Ranjith R (odoo@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 models, api, fields
class ResPartner(models.Model):
_inherit = 'res.partner'
certificate_count = fields.Integer(string="Certificate Count",
compute='_compute_total_certificates'
'_count',
help="Count of certificates")
license_count = fields.Integer(string="License Count",
compute='_compute_total_license_count',
help="Count of license")
@api.depends('license_count')
def _compute_total_certificates_count(self):
"""We can get the count of certificates"""
self.certificate_count = self.env[
'certificates'].search_count([('customer_id', '=', self.id)])
@api.depends('certificate_count')
def _compute_total_license_count(self):
"""We can get the count of license"""
self.license_count = self.env[
'license'].search_count([('customer_id', '=', self.id)])
def show_certificates(self):
"""We can see the certificate in tree and form view"""
self.ensure_one()
return {
'type': 'ir.actions.act_window',
'name': 'Certificates',
'view_mode': 'tree,form',
'res_model': 'certificates',
'domain': [('customer_id', '=', self.id)],
'context': "{'create': False}"
}
def show_license(self):
"""We can see the certificate in tree and form view"""
self.ensure_one()
return {
'type': 'ir.actions.act_window',
'name': 'License',
'view_mode': 'tree,form',
'res_model': 'license',
'domain': [('customer_id', '=', self.id)],
'context': "{'create': False}"
}

25
certificate_license_expiry/report/certificates_reports.xml

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!--Report Action to print the PDF Report of the Certificate-->
<record id="action_certificate_report" model="ir.actions.report">
<field name="name">Certificate Report</field>
<field name="model">certificates</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">certificate_license_expiry.report_certificates</field>
<field name="report_file">certificate_license_expiry.report_certificates</field>
<field name="binding_type">report</field>
</record>
<!--Server Action to print the PDF Report of the Certificate-->
<record model="ir.actions.server" id="action_create_certificate_pdf_report">
<field name="name">PDF Report</field>
<field name="model_id"
ref="certificate_license_expiry.model_certificates"/>
<field name="binding_model_id"
ref="certificate_license_expiry.model_certificates"/>
<field name="binding_view_types">form</field>
<field name="state">code</field>
<field name="code">
action = records.action_create_certificate_pdf_report()
</field>
</record>
</odoo>

150
certificate_license_expiry/report/certificates_templates.xml

@ -0,0 +1,150 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!--Template of the Certificate Report-->
<template id="report_certificates">
<t t-call="web.external_layout">
<t t-call="web.html_container">
<div class="page">
<h1 style="color:black;align:center">Certificate Report</h1>
<table class="table">
<tr>
<h2 style="color:black">
<t t-esc="record_name"/>
</h2>
</tr>
</table>
<table class="table">
<tr>
<td>
<strong>Certificate Number</strong>
</td>
<td>
<t t-esc="record_certificate_number"/>
</td>
</tr>
<tr>
<td>
<strong>Customer/Supplier/Contact</strong>
</td>
<td>
<t t-esc="record_customer_name"/>
</td>
</tr>
<tr>
<td>
<strong>Certificates Types</strong>
</td>
<td>
<t t-esc="record_certificate_type"/>
</td>
</tr>
<tr>
<td>
<strong>Start Date</strong>
</td>
<td>
<t t-esc="record_start_date"/>
</td>
</tr>
<tr>
<td>
<strong>Expired Date</strong>
</td>
<td>
<t t-esc="record_expire_date"/>
</td>
</tr>
<tr>
<td>
<strong>Issued By</strong>
</td>
<td>
<t t-esc="record_issued_by"/>
</td>
</tr>
<tr>
<td>
<strong>Project</strong>
</td>
<td>
<t t-esc="record_project"/>
</td>
</tr>
<tr>
<td>
<strong>Task</strong>
</td>
<td>
<t t-esc="record_task"/>
</td>
</tr>
<tr>
<td>
<strong>Product</strong>
</td>
<td>
<t t-esc="record_product"/>
</td>
</tr>
<tr>
<td>
<strong>Responsible Person</strong>
</td>
<td>
<t t-esc="record_user"/>
</td>
</tr>
<tr>
<td>
<strong>Company</strong>
</td>
<td>
<t t-esc="record_company"/>
</td>
</tr>
<tr>
<td>
<strong>Expire Remainder Day</strong>
</td>
<td>
<t t-esc="record_expire_remainder_day"/>
</td>
</tr>
<tr>
<td>
<strong>Status</strong>
</td>
<td>
<t t-esc="record_state"/>
</td>
</tr>
<tr>
<td>
<strong>Internal Notes</strong>
</td>
<td>
<t t-esc="record_internal_notes"/>
</td>
</tr>
<tr>
<td>
<strong>Description</strong>
</td>
<td>
<t t-esc="record_description"/>
</td>
</tr>
<tr>
<td>
<strong>Achievements</strong>
</td>
<td>
<t t-esc="record_achievements"/>
</td>
</tr>
</table>
</div>
</t>
</t>
</template>
</odoo>

24
certificate_license_expiry/report/license_reports.xml

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!--Report Action to print the PDF Report of the License-->
<record id="action_license_report" model="ir.actions.report">
<field name="name">License Report</field>
<field name="model">license</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">certificate_license_expiry.report_license</field>
<field name="report_file">certificate_license_expiry.report_license</field>
<field name="binding_type">report</field>
</record>
<!--Server Action to print the PDF Report of the License-->
<record model="ir.actions.server" id="action_create_licence_pdf_report">
<field name="name">PDF Report</field>
<field name="model_id" ref="certificate_license_expiry.model_license"/>
<field name="binding_model_id"
ref="certificate_license_expiry.model_license"/>
<field name="binding_view_types">form</field>
<field name="state">code</field>
<field name="code">
action = records.action_create_license_pdf_report()
</field>
</record>
</odoo>

150
certificate_license_expiry/report/license_templates.xml

@ -0,0 +1,150 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!--Template of the Certificate Report-->
<template id="report_license">
<t t-call="web.external_layout">
<t t-call="web.html_container">
<div class="page">
<h1 style="color:black;align:center">License Report</h1>
<table class="table">
<tr>
<h2 style="color:black">
<t t-esc="record_name"/>
</h2>
</tr>
</table>
<table class="table">
<tr>
<td>
<strong>License Number</strong>
</td>
<td>
<t t-esc="record_license_number"/>
</td>
</tr>
<tr>
<td>
<strong>Customer/Supplier/Contact</strong>
</td>
<td>
<t t-esc="record_customer"/>
</td>
</tr>
<tr>
<td>
<strong>License Types</strong>
</td>
<td>
<t t-esc="record_license_type"/>
</td>
</tr>
<tr>
<td>
<strong>Start Date</strong>
</td>
<td>
<t t-esc="record_start_date"/>
</td>
</tr>
<tr>
<td>
<strong>Expired Date</strong>
</td>
<td>
<t t-esc="record_expire_date"/>
</td>
</tr>
<tr>
<td>
<strong>Issued By</strong>
</td>
<td>
<t t-esc="record_issued_by_"/>
</td>
</tr>
<tr>
<td>
<strong>Project</strong>
</td>
<td>
<t t-esc="record_project"/>
</td>
</tr>
<tr>
<td>
<strong>Task</strong>
</td>
<td>
<t t-esc="record_task"/>
</td>
</tr>
<tr>
<td>
<strong>Product</strong>
</td>
<td>
<t t-esc="record_product"/>
</td>
</tr>
<tr>
<td>
<strong>Responsible Person</strong>
</td>
<td>
<t t-esc="record_user"/>
</td>
</tr>
<tr>
<td>
<strong>Company</strong>
</td>
<td>
<t t-esc="record_company"/>
</td>
</tr>
<tr>
<td>
<strong>Expire Remainder Day</strong>
</td>
<td>
<t t-esc="record_expire_remainder_day"/>
</td>
</tr>
<tr>
<td>
<strong>Status</strong>
</td>
<td>
<t t-esc="record_state"/>
</td>
</tr>
<tr>
<td>
<strong>Internal Notes</strong>
</td>
<td>
<t t-esc="record_internal_notes"/>
</td>
</tr>
<tr>
<td>
<strong>Description</strong>
</td>
<td>
<t t-esc="record_description"/>
</td>
</tr>
<tr>
<td>
<strong>Achievements</strong>
</td>
<td>
<t t-esc="record_achievements"/>
</td>
</tr>
</table>
</div>
</t>
</t>
</template>
</odoo>

29
certificate_license_expiry/security/certificates_license_expiry_groups.xml

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!--Category for the groups-->
<record model="ir.module.category" id="certificate_license_expiry">
<field name="name">Certificates License Expiry</field>
<field name="description">Access For Certificates License Expiry Module
</field>
<field name="sequence">10</field>
</record>
<!--Group for the Customer-->
<record id="certificates_license_expiry_group_customer" model="res.groups">
<field name="name">Customer</field>
<field name="category_id"
ref="certificate_license_expiry.certificate_license_expiry"/>
</record>
<!--Group for the Manager-->
<record id="certificate_license_expiry_group_manager" model="res.groups">
<field name="name">Manager</field>
<field name="category_id"
ref="certificate_license_expiry.certificate_license_expiry"/>
<field name="implied_ids"
eval="[(4, ref('certificates_license_expiry_group_customer'))]"/>
</record>
<!--Assigning the Manager group for the default user-->
<record id="base.default_user" model="res.users">
<field name="groups_id"
eval="[(4,ref('certificate_license_expiry_group_manager'))]"/>
</record>
</odoo>

30
certificate_license_expiry/security/certificates_security.xml

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!--Record rule of the model certificates for the managers-->
<record id="certificates_rule_manager" model="ir.rule">
<field name="name">Certificates Manager</field>
<field ref="model_certificates" name="model_id"/>
<field name="domain_force">[(1,'=',1)]</field>
<field name="groups"
eval="[(4, ref('certificate_license_expiry.certificate_license_expiry_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 of the model certificates for the customers-->
<record id="certificates_rule_customer" model="ir.rule">
<field name="name">Certificates Customer</field>
<field ref="model_certificates" name="model_id"/>
<field name="domain_force">[('customer_id','=',user.partner_id.id)]
</field>
<field name="groups"
eval="[(4, ref('certificate_license_expiry.certificates_license_expiry_group_customer'))]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_unlink" eval="False"/>
<field name="active" eval="True"/>
</record>
</odoo>

13
certificate_license_expiry/security/ir.model.access.csv

@ -0,0 +1,13 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_certificates1_customer,access.model.certificates.customer,model_certificates,certificate_license_expiry.certificates_license_expiry_group_customer,1,0,0,0
access_certificates_types1_customer,access.model.certificates.types.customer,model_certificates_types,certificate_license_expiry.certificates_license_expiry_group_customer,1,0,0,0
access_certificates_manager,access.model.certificates.manager,model_certificates,certificate_license_expiry.certificate_license_expiry_group_manager,1,1,1,1
access_certificates_types_manager,access.model.certificates.types.manager,model_certificates_types,certificate_license_expiry.certificate_license_expiry_group_manager,1,1,1,1
access_licences1_customer,access.model.license.customer,model_license,certificate_license_expiry.certificates_license_expiry_group_customer,1,0,0,0
access_license_types1_customer,access.model.license.types.customer,model_license_types,certificate_license_expiry.certificates_license_expiry_group_customer,1,0,0,0
access_license_manager,access.model.license.manager,model_license,certificate_license_expiry.certificate_license_expiry_group_manager,1,1,1,1
access_license_types_manager,access.model.license.types.manager,model_license_types,certificate_license_expiry.certificate_license_expiry_group_manager,1,1,1,1
access_license_tags1_customer,access.model.license.tags.customer,model_license_tags,certificate_license_expiry.certificates_license_expiry_group_customer,1,0,0,0
access_certificates_tags1_customer,access.model.certificates.tags.customer,model_certificates_tags,certificate_license_expiry.certificates_license_expiry_group_customer,1,0,0,0
access_license_tags_manager,access.model.license.tags.manager,model_license_tags,certificate_license_expiry.certificate_license_expiry_group_manager,1,1,1,1
access_certificates_tags_manager,access.model.certificates.tags.manager,model_certificates_tags,certificate_license_expiry.certificate_license_expiry_group_manager,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_certificates1_customer access.model.certificates.customer model_certificates certificate_license_expiry.certificates_license_expiry_group_customer 1 0 0 0
3 access_certificates_types1_customer access.model.certificates.types.customer model_certificates_types certificate_license_expiry.certificates_license_expiry_group_customer 1 0 0 0
4 access_certificates_manager access.model.certificates.manager model_certificates certificate_license_expiry.certificate_license_expiry_group_manager 1 1 1 1
5 access_certificates_types_manager access.model.certificates.types.manager model_certificates_types certificate_license_expiry.certificate_license_expiry_group_manager 1 1 1 1
6 access_licences1_customer access.model.license.customer model_license certificate_license_expiry.certificates_license_expiry_group_customer 1 0 0 0
7 access_license_types1_customer access.model.license.types.customer model_license_types certificate_license_expiry.certificates_license_expiry_group_customer 1 0 0 0
8 access_license_manager access.model.license.manager model_license certificate_license_expiry.certificate_license_expiry_group_manager 1 1 1 1
9 access_license_types_manager access.model.license.types.manager model_license_types certificate_license_expiry.certificate_license_expiry_group_manager 1 1 1 1
10 access_license_tags1_customer access.model.license.tags.customer model_license_tags certificate_license_expiry.certificates_license_expiry_group_customer 1 0 0 0
11 access_certificates_tags1_customer access.model.certificates.tags.customer model_certificates_tags certificate_license_expiry.certificates_license_expiry_group_customer 1 0 0 0
12 access_license_tags_manager access.model.license.tags.manager model_license_tags certificate_license_expiry.certificate_license_expiry_group_manager 1 1 1 1
13 access_certificates_tags_manager access.model.certificates.tags.manager model_certificates_tags certificate_license_expiry.certificate_license_expiry_group_manager 1 1 1 1

30
certificate_license_expiry/security/license_security.xml

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!--Record rule of the model license for the Manager-->
<record id="license_rule_manager" model="ir.rule">
<field name="name">License Manager</field>
<field ref="model_license" name="model_id"/>
<field name="domain_force">[(1,'=',1)]</field>
<field name="groups"
eval="[(4, ref('certificate_license_expiry.certificate_license_expiry_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 of the model license for the Customer-->
<record id="license_rule_customer" model="ir.rule">
<field name="name">License Customer</field>
<field ref="model_license" name="model_id"/>
<field name="domain_force">[('customer_id','=',user.partner_id.id)]
</field>
<field name="groups"
eval="[(4, ref('certificate_license_expiry.certificates_license_expiry_group_customer'))]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_unlink" eval="False"/>
<field name="active" eval="True"/>
</record>
</odoo>

BIN
certificate_license_expiry/static/description/assets/icons/check.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
certificate_license_expiry/static/description/assets/icons/chevron.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

BIN
certificate_license_expiry/static/description/assets/icons/cogs.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
certificate_license_expiry/static/description/assets/icons/consultation.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
certificate_license_expiry/static/description/assets/icons/ecom-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

BIN
certificate_license_expiry/static/description/assets/icons/education-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

BIN
certificate_license_expiry/static/description/assets/icons/hotel-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

BIN
certificate_license_expiry/static/description/assets/icons/license.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
certificate_license_expiry/static/description/assets/icons/lifebuoy.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
certificate_license_expiry/static/description/assets/icons/manufacturing-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

BIN
certificate_license_expiry/static/description/assets/icons/pos-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 B

BIN
certificate_license_expiry/static/description/assets/icons/puzzle.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

BIN
certificate_license_expiry/static/description/assets/icons/restaurant-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

BIN
certificate_license_expiry/static/description/assets/icons/service-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 B

BIN
certificate_license_expiry/static/description/assets/icons/trading-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

BIN
certificate_license_expiry/static/description/assets/icons/training.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

BIN
certificate_license_expiry/static/description/assets/icons/update.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
certificate_license_expiry/static/description/assets/icons/user.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 988 B

BIN
certificate_license_expiry/static/description/assets/icons/wrench.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
certificate_license_expiry/static/description/assets/misc/categories.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
certificate_license_expiry/static/description/assets/misc/check-box.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
certificate_license_expiry/static/description/assets/misc/compass.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
certificate_license_expiry/static/description/assets/misc/corporate.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
certificate_license_expiry/static/description/assets/misc/customer-support.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
certificate_license_expiry/static/description/assets/misc/cybrosys-logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
certificate_license_expiry/static/description/assets/misc/features.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 B

BIN
certificate_license_expiry/static/description/assets/misc/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
certificate_license_expiry/static/description/assets/misc/pictures.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
certificate_license_expiry/static/description/assets/misc/pie-chart.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
certificate_license_expiry/static/description/assets/misc/right-arrow.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 B

BIN
certificate_license_expiry/static/description/assets/misc/star.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
certificate_license_expiry/static/description/assets/misc/support.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
certificate_license_expiry/static/description/assets/misc/whatsapp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
certificate_license_expiry/static/description/assets/modules/1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

BIN
certificate_license_expiry/static/description/assets/modules/2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
certificate_license_expiry/static/description/assets/modules/3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
certificate_license_expiry/static/description/assets/modules/4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
certificate_license_expiry/static/description/assets/modules/5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

BIN
certificate_license_expiry/static/description/assets/modules/6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/Certificate Report.pdf

Binary file not shown.

BIN
certificate_license_expiry/static/description/assets/screenshots/active-certificate-tree-view.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/active-certificate.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/active-license-tree-view.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/active-license.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/certificate-expire-reminder-day.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/certificate-expired-mail-template.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/certificate-expiry-notification.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/certificate-group-sort.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/certificate-group-tags.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/certificate-group-type.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/certificate-kanban-view.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/certificate-license-customer-view.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/certificate-license-customer.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/certificate-license-manager.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/certificate-pdf-report-button.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/certificate-pdf-report.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/certificate-portal-form.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/certificate-portal-search.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/certificate-portal-tree.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/certificates-calendar-view.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/certificates-form-view.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/certificates-graph-view.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/certificates-licenses-submenu.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/certificates-tree-view.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/configuration-sub-menu.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/contact-certificates.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/contact-licenses.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/contact-smart-button.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/hero.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 333 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/license-calendar-view.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 332 KiB

BIN
certificate_license_expiry/static/description/assets/screenshots/license-expire-reminder-day.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save