diff --git a/access_restriction_by_ip/README.rst b/access_restriction_by_ip/README.rst new file mode 100644 index 000000000..e536733bc --- /dev/null +++ b/access_restriction_by_ip/README.rst @@ -0,0 +1,18 @@ +Access Restriction By IP V14 +============================ + +This module will restrict users access to his account from the specified IP only. If user access his +account from non-specified IP, login will be restricted and a warning message will be displayed in +login page. + +If no IP is specified for a user, then there will not be restriction by IP. He can access from any IP. + + +Credits +======= +Cybrosys Techno Solutions + +Author +------ +* Niyas Raphy +* V14 Muhammad P diff --git a/access_restriction_by_ip/__init__.py b/access_restriction_by_ip/__init__.py new file mode 100644 index 000000000..8ca207817 --- /dev/null +++ b/access_restriction_by_ip/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: Niyas Raphy() +# you can modify it under the terms of the GNU LESSER +# 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 LESSER GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (AGPL v3) along with this program. +# If not, see . +# +############################################################################## +from . import controllers +from . import models + + diff --git a/access_restriction_by_ip/__manifest__.py b/access_restriction_by_ip/__manifest__.py new file mode 100644 index 000000000..a050d773a --- /dev/null +++ b/access_restriction_by_ip/__manifest__.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2020-TODAY Cybrosys Technologies(). +# you can modify it under the terms of the GNU LESSER +# 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 LESSER GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (AGPL v3) along with this program. +# If not, see . +# +############################################################################## +{ + 'name': 'Access Restriction By IP', + 'summary': """User Can Access His Account Only From Specified IP Address""", + 'version': '14.0.1.0.0', + 'description': """User Can Access His Account Only From Specified IP Address""", + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'website': 'https://www.cybrosys.com', + 'category': 'Tools', + 'depends': ['base', 'mail'], + 'license': 'AGPL-3', + 'data': [ + 'security/ir.model.access.csv', + 'views/allowed_ips_view.xml', + ], + 'images': ['static/description/banner.png'], + 'installable': True, + 'auto_install': False, +} + diff --git a/access_restriction_by_ip/controllers/__init__.py b/access_restriction_by_ip/controllers/__init__.py new file mode 100644 index 000000000..1939c6696 --- /dev/null +++ b/access_restriction_by_ip/controllers/__init__.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: Niyas Raphy() +# you can modify it under the terms of the GNU LESSER +# 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 LESSER GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (AGPL v3) along with this program. +# If not, see . +# +############################################################################## +from . import main + diff --git a/access_restriction_by_ip/controllers/main.py b/access_restriction_by_ip/controllers/main.py new file mode 100644 index 000000000..547c6b633 --- /dev/null +++ b/access_restriction_by_ip/controllers/main.py @@ -0,0 +1,89 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2020-TODAY Cybrosys Technologies(). +# Author: Niyas Raphy() +# you can modify it under the terms of the GNU LESSER +# 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 LESSER GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (AGPL v3) along with this program. +# If not, see . +# +############################################################################## +from odoo.addons.web.controllers import main +from odoo.http import request +from odoo.exceptions import Warning +import odoo +import odoo.modules.registry +from odoo.tools.translate import _ +from odoo import http + + +class Home(main.Home): + + @http.route('/web/login', type='http', auth="public") + def web_login(self, redirect=None, **kw): + main.ensure_db() + request.params['login_success'] = False + if request.httprequest.method == 'GET' and redirect and request.session.uid: + return http.redirect_with_hash(redirect) + + if not request.uid: + request.uid = odoo.SUPERUSER_ID + + values = request.params.copy() + try: + values['databases'] = http.db_list() + except odoo.exceptions.AccessDenied: + values['databases'] = None + if request.httprequest.method == 'POST': + old_uid = request.uid + ip_address = request.httprequest.environ['REMOTE_ADDR'] + if request.params['login']: + user_rec = request.env['res.users'].sudo().search( + [('login', '=', request.params['login'])]) + if user_rec.allowed_ips: + ip_list = [] + for rec in user_rec.allowed_ips: + ip_list.append(rec.ip_address) + if ip_address in ip_list: + try: + uid = request.session.authenticate( + request.session.db, + request.params[ + 'login'], + request.params[ + 'password']) + request.params['login_success'] = True + return http.redirect_with_hash( + self._login_redirect(uid, redirect=redirect)) + except odoo.exceptions.AccessDenied as e: + request.uid = old_uid + if e.args == odoo.exceptions.AccessDenied().args: + values['error'] = _("Wrong login/password") + else: + request.uid = old_uid + values['error'] = _("Not allowed to login from this IP") + else: + try: + uid = request.session.authenticate(request.session.db, + request.params[ + 'login'], + request.params[ + 'password']) + request.params['login_success'] = True + return http.redirect_with_hash( + self._login_redirect(uid, redirect=redirect)) + except odoo.exceptions.AccessDenied as e: + request.uid = old_uid + if e.args == odoo.exceptions.AccessDenied().args: + values['error'] = _("Wrong login/password") + + return request.render('web.login', values) diff --git a/access_restriction_by_ip/doc/RELEASE_NOTES.md b/access_restriction_by_ip/doc/RELEASE_NOTES.md new file mode 100644 index 000000000..2cf0f8024 --- /dev/null +++ b/access_restriction_by_ip/doc/RELEASE_NOTES.md @@ -0,0 +1,5 @@ +## Module + +#### 08.10.2020 +#### Version 14.0.1.0.0 +#### ADD Initial Commit for access_restriction_by_ip \ No newline at end of file diff --git a/access_restriction_by_ip/models/__init__.py b/access_restriction_by_ip/models/__init__.py new file mode 100644 index 000000000..ca519c454 --- /dev/null +++ b/access_restriction_by_ip/models/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: Niyas Raphy() +# you can modify it under the terms of the GNU LESSER +# 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 LESSER GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (AGPL v3) along with this program. +# If not, see . +# +############################################################################## +from . import allowed_ips + + diff --git a/access_restriction_by_ip/models/allowed_ips.py b/access_restriction_by_ip/models/allowed_ips.py new file mode 100644 index 000000000..105e2a2f3 --- /dev/null +++ b/access_restriction_by_ip/models/allowed_ips.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: Niyas Raphy() +# you can modify it under the terms of the GNU LESSER +# 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 LESSER GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (AGPL v3) along with this program. +# If not, see . +# +############################################################################## +from odoo import models, fields + + +class ResUsersInherit(models.Model): + _inherit = 'res.users' + + allowed_ips = fields.One2many('allowed.ips', 'users_ip', string='IP') + + +class AllowedIPs(models.Model): + _name = 'allowed.ips' + + users_ip = fields.Many2one('res.users', string='IP') + ip_address = fields.Char(string='Allowed IP') diff --git a/access_restriction_by_ip/security/ir.model.access.csv b/access_restriction_by_ip/security/ir.model.access.csv new file mode 100644 index 000000000..c6ee084c4 --- /dev/null +++ b/access_restriction_by_ip/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_allowed_ips,access.allowed.ips,access_restriction_by_ip.model_allowed_ips,base.group_user,1,1,1,0 diff --git a/access_restriction_by_ip/static/description/banner.png b/access_restriction_by_ip/static/description/banner.png new file mode 100644 index 000000000..4eea08296 Binary files /dev/null and b/access_restriction_by_ip/static/description/banner.png differ diff --git a/access_restriction_by_ip/static/description/icon.png b/access_restriction_by_ip/static/description/icon.png new file mode 100644 index 000000000..22ed2a2c7 Binary files /dev/null and b/access_restriction_by_ip/static/description/icon.png differ diff --git a/access_restriction_by_ip/static/description/images/Ip adding.png b/access_restriction_by_ip/static/description/images/Ip adding.png new file mode 100644 index 000000000..3aabf51a4 Binary files /dev/null and b/access_restriction_by_ip/static/description/images/Ip adding.png differ diff --git a/access_restriction_by_ip/static/description/images/Ip.png b/access_restriction_by_ip/static/description/images/Ip.png new file mode 100644 index 000000000..e7f9ebcf9 Binary files /dev/null and b/access_restriction_by_ip/static/description/images/Ip.png differ diff --git a/access_restriction_by_ip/static/description/images/banner_lifeline_for_task.jpeg b/access_restriction_by_ip/static/description/images/banner_lifeline_for_task.jpeg new file mode 100644 index 000000000..4a467ea22 Binary files /dev/null and b/access_restriction_by_ip/static/description/images/banner_lifeline_for_task.jpeg differ diff --git a/access_restriction_by_ip/static/description/images/banner_project_report_xls_pdf.png b/access_restriction_by_ip/static/description/images/banner_project_report_xls_pdf.png new file mode 100644 index 000000000..3c430a7eb Binary files /dev/null and b/access_restriction_by_ip/static/description/images/banner_project_report_xls_pdf.png differ diff --git a/access_restriction_by_ip/static/description/images/banner_project_status_report.png b/access_restriction_by_ip/static/description/images/banner_project_status_report.png new file mode 100644 index 000000000..d1b689710 Binary files /dev/null and b/access_restriction_by_ip/static/description/images/banner_project_status_report.png differ diff --git a/access_restriction_by_ip/static/description/images/banner_subtask.jpeg b/access_restriction_by_ip/static/description/images/banner_subtask.jpeg new file mode 100644 index 000000000..f2b224110 Binary files /dev/null and b/access_restriction_by_ip/static/description/images/banner_subtask.jpeg differ diff --git a/access_restriction_by_ip/static/description/images/banner_task_deadline_reminder.jpeg b/access_restriction_by_ip/static/description/images/banner_task_deadline_reminder.jpeg new file mode 100644 index 000000000..998679818 Binary files /dev/null and b/access_restriction_by_ip/static/description/images/banner_task_deadline_reminder.jpeg differ diff --git a/access_restriction_by_ip/static/description/images/banner_task_statusbar.jpeg b/access_restriction_by_ip/static/description/images/banner_task_statusbar.jpeg new file mode 100644 index 000000000..2c57cbb7b Binary files /dev/null and b/access_restriction_by_ip/static/description/images/banner_task_statusbar.jpeg differ diff --git a/access_restriction_by_ip/static/description/images/checked.png b/access_restriction_by_ip/static/description/images/checked.png new file mode 100644 index 000000000..578cedb80 Binary files /dev/null and b/access_restriction_by_ip/static/description/images/checked.png differ diff --git a/access_restriction_by_ip/static/description/images/cybrosys.png b/access_restriction_by_ip/static/description/images/cybrosys.png new file mode 100644 index 000000000..d76b5bafb Binary files /dev/null and b/access_restriction_by_ip/static/description/images/cybrosys.png differ diff --git a/access_restriction_by_ip/static/description/images/log in.png b/access_restriction_by_ip/static/description/images/log in.png new file mode 100644 index 000000000..b2138cd5d Binary files /dev/null and b/access_restriction_by_ip/static/description/images/log in.png differ diff --git a/access_restriction_by_ip/static/description/images/task_timer_youtube.png b/access_restriction_by_ip/static/description/images/task_timer_youtube.png new file mode 100644 index 000000000..fb6579727 Binary files /dev/null and b/access_restriction_by_ip/static/description/images/task_timer_youtube.png differ diff --git a/access_restriction_by_ip/static/description/index.html b/access_restriction_by_ip/static/description/index.html new file mode 100644 index 000000000..e9f25709d --- /dev/null +++ b/access_restriction_by_ip/static/description/index.html @@ -0,0 +1,310 @@ +
cybrosys-logo
+
+
+
+

Access Restriction By IP

+

User can access his account only from specified IP's

+
+

Key Highlights

+
    +
  • Administrator can set a IP or a group of IP address for each users
  • +
  • Users can access their account only from the specified IP's
  • +
  • Accessing system from a non-specified IP will restrict the user login
  • +
  • A warning message will be displayed
  • +
  • If no IP is set to user means there is not any restriction by IP
  • +
  • IP Address for each users can be set from users form view
  • + +
+
+
+
+ +
+
+
+
+ +
+
+ +

Overview

+
+

+ This module will restrict the users access to his account from specified IP address only

+
+
+ +

Access Restriction By IP

+
+
    +
  • + Administrator can set a IP or a group of IP address for each users +
  • + +
  • + Users can access their account only from the specified IP's +
  • + +
  • + Accessing system from a non-specified IP will restrict the user login +
  • + +
  • + A warning message will be displayed +
  • + +
  • + If no IP is set to user means there is not any restriction by IP +
  • + +
  • + IP Address for each users can be set from users form view +
  • +
+
+ +
+
+

Screenshots

+
+
+
+ +
+
+
+
+ + +
+
    +
+
+
+
+
+
+
+

Suggested Products

+
+ +
+
+

Our Service

+
+ +
+
+
+

Our Industries

+
+ +
+
+
+ +
+
+

Trading

+

Easily procure and sell your products.

+
+
+
+
+ +
+
+

Manufacturing

+

Plan, track and schedule your operations.

+
+
+
+
+ +
+
+

Restaurant

+

Run your bar or restaurant methodical.

+
+
+
+
+ +
+
+

POS

+

Easy configuring and convivial selling.

+
+
+
+
+ +
+
+

E-commerce & Website

+

Mobile friendly, awe-inspiring product pages.

+
+
+
+
+ +
+
+

Hotel Management

+

An all-inclusive hotel management application.

+
+
+
+
+ +
+
+

Education

+

A Collaborative platform for educational management.

+
+
+
+
+ +
+
+

Service Management

+

Keep track of services and invoice accordingly.

+
+
+
+
+
+ +
+
+
+

Need Any Help?

+
+

If you have anything to share with us based on your use of this module, please let us know. We are ready to offer our support.

+
+

Email us

+

odoo@cybrosys.com / info@cybrosys.com

+
+
+

Contact Us

+ www.cybrosys.com +
+
+
+
+
+
+
+
+
+ +
+ + + + + + + +
+
+
+ \ No newline at end of file diff --git a/access_restriction_by_ip/views/allowed_ips_view.xml b/access_restriction_by_ip/views/allowed_ips_view.xml new file mode 100644 index 000000000..a5a528fb1 --- /dev/null +++ b/access_restriction_by_ip/views/allowed_ips_view.xml @@ -0,0 +1,21 @@ + + + + + res.users + res.users + + + + + + + + + + + + + + + diff --git a/login_user_detail/README.rst b/login_user_detail/README.rst new file mode 100755 index 000000000..effc19e63 --- /dev/null +++ b/login_user_detail/README.rst @@ -0,0 +1,53 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--1-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +User Log Details +================ + +This module developed to record login details of user. + +Installation +============ + +Just select it from available modules to install it, there is no need to extra installations. + +Configuration +============= + +Nothing to configure. + +Company +------- +* `Cybrosys Techno Solutions `__ + +Credits +------- +* Developer: + Saritha @ cybrosys + Muhammad P @ cybrosys + +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 `__ + +Further information +=================== +HTML Description: ``__ + + + diff --git a/login_user_detail/__init__.py b/login_user_detail/__init__.py new file mode 100755 index 000000000..4d63b6757 --- /dev/null +++ b/login_user_detail/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Your Name (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 . +# +############################################################################# + +from . import models diff --git a/login_user_detail/__manifest__.py b/login_user_detail/__manifest__.py new file mode 100755 index 000000000..25b6a8afa --- /dev/null +++ b/login_user_detail/__manifest__.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2020-TODAY Cybrosys Technologies(). +# +# 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 . +# +############################################################################# + +{ + 'name': "User Log Details", + 'version': '14.0.1.0.0', + 'summary': """Login User Details & IP Address""", + 'description': """This module records login information of user""", + 'author': "Cybrosys Techno Solutions ", + 'company': "Cybrosys Techno Solutions ", + 'maintainer': 'Cybrosys Techno Solutions', + 'website': "https://www.cybrosys.com", + 'category': 'Tools', + 'depends': ['base'], + 'license': 'AGPL-3', + 'data': [ + 'security/ir.model.access.csv', + 'views/login_user_views.xml'], + 'demo': [], + 'images': ['static/description/banner.png'], + 'installable': True, + 'auto_install': False, +} diff --git a/login_user_detail/doc/RELEASE_NOTES.md b/login_user_detail/doc/RELEASE_NOTES.md new file mode 100644 index 000000000..011112d1a --- /dev/null +++ b/login_user_detail/doc/RELEASE_NOTES.md @@ -0,0 +1,6 @@ +## Module + +#### 08.10.2020 +#### Version 14.0.1.0.0 +#### ADD +- Initial Commit for login_user_details \ No newline at end of file diff --git a/login_user_detail/models/__init__.py b/login_user_detail/models/__init__.py new file mode 100755 index 000000000..52c913351 --- /dev/null +++ b/login_user_detail/models/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Your Name (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 . +# +############################################################################# + +from . import login_user_details diff --git a/login_user_detail/models/login_user_details.py b/login_user_detail/models/login_user_details.py new file mode 100755 index 000000000..a3d13d5c5 --- /dev/null +++ b/login_user_detail/models/login_user_details.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Your Name (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 . +# +############################################################################# + +import logging +from itertools import chain +from odoo.http import request +from odoo import models, fields, api + +_logger = logging.getLogger(__name__) +USER_PRIVATE_FIELDS = ['password'] +concat = chain.from_iterable + + +class LoginUserDetail(models.Model): + _inherit = 'res.users' + + @api.model + def _check_credentials(self, password, user_agent_env): + result = super(LoginUserDetail, self)._check_credentials(password, user_agent_env) + ip_address = request.httprequest.environ['REMOTE_ADDR'] + vals = {'name': self.name, + 'ip_address': ip_address + } + self.env['login.detail'].sudo().create(vals) + return result + + +class LoginUpdate(models.Model): + _name = 'login.detail' + + name = fields.Char(string="User Name") + date_time = fields.Datetime(string="Login Date And Time", default=lambda self: fields.datetime.now()) + ip_address = fields.Char(string="IP Address") diff --git a/login_user_detail/security/ir.model.access.csv b/login_user_detail/security/ir.model.access.csv new file mode 100755 index 000000000..7935bc9e7 --- /dev/null +++ b/login_user_detail/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_login_user_detail,login_user_detail_login_detail,model_login_detail,,1,1,1,1 diff --git a/login_user_detail/static/description/banner.png b/login_user_detail/static/description/banner.png new file mode 100644 index 000000000..31410811d Binary files /dev/null and b/login_user_detail/static/description/banner.png differ diff --git a/login_user_detail/static/description/cybro_logo.png b/login_user_detail/static/description/cybro_logo.png new file mode 100755 index 000000000..bb309114c Binary files /dev/null and b/login_user_detail/static/description/cybro_logo.png differ diff --git a/login_user_detail/static/description/cybrosys-login-user-details.png b/login_user_detail/static/description/cybrosys-login-user-details.png new file mode 100755 index 000000000..38477eeed Binary files /dev/null and b/login_user_detail/static/description/cybrosys-login-user-details.png differ diff --git a/login_user_detail/static/description/icon.png b/login_user_detail/static/description/icon.png new file mode 100644 index 000000000..38c4a62b2 Binary files /dev/null and b/login_user_detail/static/description/icon.png differ diff --git a/login_user_detail/static/description/index.html b/login_user_detail/static/description/index.html new file mode 100755 index 000000000..e02fe7d4f --- /dev/null +++ b/login_user_detail/static/description/index.html @@ -0,0 +1,310 @@ +
+
+

+ User Log Details +

+

+ Records User Log Details +

+
+ Cybrosys Technologies +
+ +
+ cybrosys technologies +
+
+
+
+ +
+
+

+ Overview +

+

+ User Log Details, Record login date,IP Address of login user. +

+
+
+
+
+

+ Screenshots +

+

+ + Login Details +

+
+ +
+
+
+ +
+
+ cybrosys technologies +
+
+
+
+

+ Our Services +

+
+ + + +
+ +
+ + + +
+

+ + Odoo Support +

+ +
+ +
+
+
+
+
+

+ Our Industries +

+
+
+ +
+
+ + Odoo Industry + +
+
+
+

+ + Trading + +

+

+ Easily procure and sell your products. +

+
+ +
+
+ +
+
+ + Odoo Industry + +
+
+
+

+ + Manufacturing +

+

+ Plan, track and schedule your operations. +

+
+ +
+
+ +
+
+ + Odoo Industry + +
+
+
+

+ + Restaurant +

+

+ Run your bar or restaurant methodical. +

+
+ +
+
+ +
+
+ + Odoo Industry + +
+
+
+

+ + POS +

+

+ Easy configuring and convivial selling. +

+
+ +
+
+ +
+
+ + Odoo Industry + +
+
+
+

+ + E-commerce & Website +

+

+ Mobile friendly, awe-inspiring product pages. +

+
+
+
+ +
+
+ + Odoo Industry + +
+
+
+

+ + Hotel Management +

+

+ An all-inclusive hotel management application. +

+
+
+
+ +
+
+ + Odoo Industry + +
+
+
+

+ + Education +

+

+ A Collaborative platform for educational management. +

+
+
+
+ +
+
+ + Odoo Industry + +
+
+
+

+ + Service Management +

+

+ Keep track of services and invoice accordingly. +

+
+
+
+
+
+
+ +
+ diff --git a/login_user_detail/static/description/login.png b/login_user_detail/static/description/login.png new file mode 100755 index 000000000..38477eeed Binary files /dev/null and b/login_user_detail/static/description/login.png differ diff --git a/login_user_detail/views/login_user_views.xml b/login_user_detail/views/login_user_views.xml new file mode 100755 index 000000000..1b49d4f1c --- /dev/null +++ b/login_user_detail/views/login_user_views.xml @@ -0,0 +1,42 @@ + + + + + Login User Details + login.detail + +
+ + + + + + + +
+
+
+ + + Login User Details + login.detail + + + + + + + + + + + Login User Details + login.detail + tree,form + + + + +
+
\ No newline at end of file diff --git a/medical_lab_management/README.rst b/medical_lab_management/README.rst new file mode 100644 index 000000000..d68101090 --- /dev/null +++ b/medical_lab_management/README.rst @@ -0,0 +1,41 @@ +Medical Lab Management v14 +========================== +Helps You To Manage Medical Lab Operations. + + +Configuration +============= +* No additional configurations needed + +Company +------- +* `Cybrosys Techno Solutions `__ + +Credits +------- +* Developers: Anusha P P @ cybrosys + Niyas Raphy @ cybrosys + V14 Muhammad P @ cybrosys + +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 `__ + +Further information +=================== +HTML Description: ``__ + diff --git a/medical_lab_management/__init__.py b/medical_lab_management/__init__.py new file mode 100644 index 000000000..627a7d13f --- /dev/null +++ b/medical_lab_management/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Anusha P P @ cybrosys and Niyas Raphy @ cybrosys(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 . +# +############################################################################# + +from . import models diff --git a/medical_lab_management/__manifest__.py b/medical_lab_management/__manifest__.py new file mode 100644 index 000000000..51775e5ee --- /dev/null +++ b/medical_lab_management/__manifest__.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2020-TODAY Cybrosys Technologies(). +# +# 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 . +# +############################################################################# + +{ + 'name': "Medical Lab Management", + 'version': '14.0.1.0.0', + 'summary': """Manage Medical Lab Operations.""", + 'description': """Manage Medical Lab General Operations, Odoo13, Odoo 13""", + 'author': "Cybrosys Techno Solutions", + 'maintainer': 'Cybrosys Techno Solutions', + 'company': "Cybrosys Techno Solutions", + 'website': "https://www.cybrosys.com", + 'category': 'Industries', + 'depends': ['base', 'mail', 'account'], + 'data': [ + 'security/lab_users.xml', + 'security/ir.model.access.csv', + 'views/res_partner.xml', + 'views/lab_patient_view.xml', + 'views/test_unit_view.xml', + 'views/lab_test_type.xml', + 'views/lab_test_content_type.xml', + 'views/physician_specialty.xml', + 'views/physician_details.xml', + 'views/lab_request.xml', + 'views/lab_appointment.xml', + 'views/account_invoice.xml', + 'report/report.xml', + 'report/lab_test_report.xml', + 'report/lab_patient_card.xml', + ], + 'images': ['static/description/banner.png'], + 'license': 'AGPL-3', + 'installable': True, + 'auto_install': False, + 'application': True, +} diff --git a/medical_lab_management/doc/RELEASE_NOTES.md b/medical_lab_management/doc/RELEASE_NOTES.md new file mode 100644 index 000000000..22b4dc009 --- /dev/null +++ b/medical_lab_management/doc/RELEASE_NOTES.md @@ -0,0 +1,8 @@ +## Module + +#### 08.10.2020 +#### Version 14.0.1.0.0 +#### ADD +Initial Commit + + diff --git a/medical_lab_management/models/__init__.py b/medical_lab_management/models/__init__.py new file mode 100644 index 000000000..dbb0454a3 --- /dev/null +++ b/medical_lab_management/models/__init__.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Anusha P P @ cybrosys and Niyas Raphy @ cybrosys(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 . +# +############################################################################# + +from . import physician_speciality +from . import res_partner +from . import lab_patient +from . import testing_unit +from . import lab_test_type +from . import lab_test_content_type +from . import lab_appointment +from . import lab_request +from . import account_invoice + + diff --git a/medical_lab_management/models/account_invoice.py b/medical_lab_management/models/account_invoice.py new file mode 100644 index 000000000..a3b9e3a12 --- /dev/null +++ b/medical_lab_management/models/account_invoice.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Anusha P P @ cybrosys and Niyas Raphy @ cybrosys(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 . +# +############################################################################# + +from odoo import models, fields, api + + +class LabRequestInvoices(models.Model): + _inherit = 'account.move' + + is_lab_invoice = fields.Boolean(string="Is Lab Invoice") + lab_request = fields.Many2one('lab.appointment', string="Lab Appointment", help="Source Document") + + def action_invoice_paid(self): + res = super(LabRequestInvoices, self).action_invoice_paid() + lab_app_obj = self.env['lab.appointment'].search([('id', '=', self.lab_request.id)]) + for obj in lab_app_obj: + obj.write({'state': 'invoiced'}) + return res diff --git a/medical_lab_management/models/lab_appointment.py b/medical_lab_management/models/lab_appointment.py new file mode 100644 index 000000000..a4c76ff28 --- /dev/null +++ b/medical_lab_management/models/lab_appointment.py @@ -0,0 +1,199 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Anusha P P @ cybrosys and Niyas Raphy @ cybrosys(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 . +# +############################################################################# + +import datetime +from odoo.exceptions import UserError +from odoo import fields, models, api, _ + + +class Appointment(models.Model): + _name = 'lab.appointment' + _inherit = ['mail.thread'] + _rec_name = 'name' + _description = "Appointment" + _order = 'appointment_date' + + user_id = fields.Many2one('res.users', 'Responsible', readonly=True) + patient_id = fields.Many2one('lab.patient', string='Patient', required=True, select=True, + help='Patient Name') + name = fields.Char(string='Appointment ID', readonly=True, default=lambda self: _('New')) + date = fields.Datetime(string='Requested Date', default=lambda s: fields.Datetime.now(), + help="This is the date in which patient appointment is noted") + appointment_date = fields.Datetime(string='Appointment Date', default=lambda s: fields.Datetime.now(), + help="This is the appointment date") + physician_id = fields.Many2one('res.partner', string='Referred By', select=True) + comment = fields.Text(string='Comments') + appointment_lines = fields.One2many('lab.appointment.lines', 'test_line_appointment', string="Test Request") + + request_count = fields.Integer(compute="_compute_state", string='# of Requests', copy=False, default=0) + inv_count = fields.Integer(compute="_compute_state", string='# of Invoices', copy=False, default=0) + state = fields.Selection([ + ('draft', 'Draft'), + ('confirm', 'Confirmed'), + ('request_lab', 'Lab Requested'), + ('completed', 'Test Result'), + ('to_invoice', 'To Invoice'), + ('invoiced', 'Done'), + ('cancel', 'Cancelled'), + ], string='Status', readonly=True, copy=False, index=True, track_visibility='onchange', default='draft', + ) + + priority = fields.Selection([ + ('0', 'Low'), + ('1', 'Normal'), + ('2', 'High') + ], size=1) + + _defaults = { + 'priority': '0', + } + + @api.model + def create(self, vals): + if vals: + vals['name'] = self.env['ir.sequence'].next_by_code('lab.appointment') or _('New') + result = super(Appointment, self).create(vals) + return result + + def _compute_state(self): + for obj in self: + obj.request_count = self.env['lab.request'].search_count([('app_id', '=', obj.id)]) + obj.inv_count = self.env['account.move'].search_count([('lab_request', '=', obj.id)]) + + def create_invoice(self): + invoice_obj = self.env["account.move"] + invoice_line_obj = self.env["account.move.line"] + journal = self.env['account.journal'].search([('type', '=', 'sale')], limit=1) + # prd_account_id = journal.default_credit_account_id.id + prd_account_id = journal.default_account_id.id + for lab in self: + lab.write({'state': 'to_invoice'}) + if lab.patient_id: + curr_invoice = { + 'partner_id': lab.patient_id.patient.id, + # 'account_id': lab.patient_id.patient.property_account_receivable_id.id, + 'state': 'draft', + 'move_type': 'out_invoice', + 'invoice_date': str(datetime.datetime.now()), + 'invoice_origin': "Lab Test# : " + lab.name, + # 'target': 'new', + 'lab_request': lab.id, + 'is_lab_invoice': True, + } + + inv_ids = invoice_obj.create(curr_invoice) + inv_id = inv_ids.id + + if inv_ids: + journal = self.env['account.journal'].search([('type', '=', 'sale')], limit=1) + prd_account_id = journal.default_account_id.id + list_value = [] + if lab.appointment_lines: + for line in lab.appointment_lines: + list_value.append((0,0, { + 'name': line.lab_test.lab_test, + 'price_unit': line.cost, + 'quantity': 1.0, + 'account_id': prd_account_id, + 'move_id': inv_id, + })) + print(list_value) + inv_ids.write({'invoice_line_ids': list_value}) + # invoice_line_obj.update({ + # 'name': line.lab_test.lab_test, + # 'price_unit': line.cost, + # 'quantity': 1.0, + # 'account_id': prd_account_id, + # 'move_id': inv_id, + # }) + + + self.write({'state': 'invoiced'}) + view_id = self.env.ref('account.view_move_form').id + return { + 'view_mode': 'form', + 'res_model': 'account.move', + 'view_id': view_id, + 'type': 'ir.actions.act_window', + 'name': _('Lab Invoices'), + 'res_id': inv_id + } + + def action_request(self): + if self.appointment_lines: + for line in self.appointment_lines: + data = self.env['lab.test'].search([('lab_test', '=', line.lab_test.lab_test)]) + self.env['lab.request'].create({'lab_request_id': self.name, + 'app_id': self.id, + 'lab_requestor': self.patient_id.id, + 'lab_requesting_date': self.appointment_date, + 'test_request': line.lab_test.id, + 'request_line': [(6, 0, [x.id for x in data.test_lines])], + }) + self.state = 'request_lab' + else: + raise UserError(_('Please Select Lab Test.')) + + def confirm_appointment(self): + + message_body = "Dear " + self.patient_id.patient.name + "," + "
Your Appointment Has been Confirmed " \ + + "
Appointment ID : " + self.name + "
Date : " + str(self.appointment_date) + \ + '

Thank you' + + template_obj = self.env['mail.mail'] + template_data = { + 'subject': 'Appointment Confirmation', + 'body_html': message_body, + 'email_from': self.env.user.company_id.email, + 'email_to': self.patient_id.email + } + template_id = template_obj.create(template_data) + template_obj.send(template_id) + self.write({'state': 'confirm'}) + + def cancel_appointment(self): + return self.write({'state': 'cancel'}) + + +class LabAppointmentLines(models.Model): + _name = 'lab.appointment.lines' + + lab_test = fields.Many2one('lab.test', string="Test") + cost = fields.Float(string="Cost") + requesting_date = fields.Date(string="Date") + test_line_appointment = fields.Many2one('lab.appointment', string="Appointment") + + @api.onchange('lab_test') + def cost_update(self): + if self.lab_test: + self.cost = self.lab_test.test_cost + + +class LabPatientInherit(models.Model): + _inherit = 'lab.patient' + + app_count = fields.Integer(compute="_compute_state", string='# of Appointments', copy=False, default=0) + + def _compute_state(self): + for obj in self: + obj.app_count = self.env['lab.appointment'].search_count([('patient_id', '=', obj.id)]) + diff --git a/medical_lab_management/models/lab_patient.py b/medical_lab_management/models/lab_patient.py new file mode 100644 index 000000000..851ced606 --- /dev/null +++ b/medical_lab_management/models/lab_patient.py @@ -0,0 +1,79 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Anusha P P @ cybrosys and Niyas Raphy @ cybrosys(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 . +# +############################################################################# + +from dateutil.relativedelta import relativedelta +from odoo import models, fields, api, _ + + +class LabPatient(models.Model): + _name = 'lab.patient' + _rec_name = 'patient' + _description = 'Patient' + + patient = fields.Many2one('res.partner', string='Partner', required=True) + patient_image = fields.Binary(string='Photo') + patient_id = fields.Char(string='Patient ID', readonly=True) + name = fields.Char(string='Patient ID', default=lambda self: _('New')) + title = fields.Selection([ + ('ms', 'Miss'), + ('mister', 'Mister'), + ('mrs', 'Mrs'), + ], string='Title', default='mister', required=True) + emergency_contact = fields.Many2one( + 'res.partner', string='Emergency Contact') + gender = fields.Selection( + [('m', 'Male'), ('f', 'Female'), + ('ot', 'Other')], 'Gender', required=True) + dob = fields.Date(string='Date Of Birth', required=True) + age = fields.Char(string='Age', compute='compute_age') + blood_group = fields.Selection( + [('A+', 'A+ve'), ('B+', 'B+ve'), ('O+', 'O+ve'), ('AB+', 'AB+ve'), + ('A-', 'A-ve'), ('B-', 'B-ve'), ('O-', 'O-ve'), ('AB-', 'AB-ve')], + 'Blood Group') + visa_info = fields.Char(string='Visa Info', size=64) + id_proof_number = fields.Char(string='ID Proof Number') + note = fields.Text(string='Note') + date = fields.Datetime(string='Date Requested', default=lambda s: fields.Datetime.now(), invisible=True) + phone = fields.Char(string="Phone", required=True) + email = fields.Char(string="Email", required=True) + + def compute_age(self): + for data in self: + if data.dob: + dob = fields.Datetime.from_string(data.dob) + date = fields.Datetime.from_string(data.date) + delta = relativedelta(date, dob) + data.age = str(delta.years) + ' years' + else: + data.age = '' + + @api.model + def create(self, vals): + sequence = self.env['ir.sequence'].next_by_code('lab.patient') + vals['name'] = sequence or _('New') + result = super(LabPatient, self).create(vals) + return result + + @api.onchange('patient') + def detail_get(self): + self.phone = self.patient.phone + self.email = self.patient.email diff --git a/medical_lab_management/models/lab_request.py b/medical_lab_management/models/lab_request.py new file mode 100644 index 000000000..f0867e0be --- /dev/null +++ b/medical_lab_management/models/lab_request.py @@ -0,0 +1,128 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Anusha P P @ cybrosys and Niyas Raphy @ cybrosys(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 . +# +############################################################################# + +import datetime +from odoo import models, fields, api, _ +from odoo.exceptions import ValidationError + + +class LabRequest(models.Model): + _name = 'lab.request' + _inherit = ['mail.thread'] + _rec_name = 'lab_request_id' + _description = 'Lab Request' + + name = fields.Char(string='Lab Test', size=16, readonly=True, required=True, help="Lab result ID", default=lambda *a: '#') + lab_request_id = fields.Char(string='Appointment ID', help="Lab appointment ID") + app_id = fields.Many2one('lab.appointment', string='Appointment') + lab_requestor = fields.Many2one('lab.patient', string='Patient', required=True, select=True, + help='Patient Name') + test_request = fields.Many2one('lab.test', string='Test') + lab_requesting_date = fields.Datetime(string='Requested Date') + comment = fields.Text('Comment') + request_line = fields.One2many('lab.test.attribute', 'test_request_reverse', string="Test Lines") + state = fields.Selection([ + ('draft', 'Draft'), + ('sample_collection', 'Sample Collected'), + ('test_in_progress', 'Test In Progress'), + ('completed', 'Completed'), + ('cancel', 'Cancelled'), + + ], string='Status', readonly=True, copy=False, index=True, track_visibility='onchange', default='draft') + + @api.model + def create(self, vals): + sequence = self.env['ir.sequence'].next_by_code('lab.request') + vals['name'] = sequence or '/' + return super(LabRequest, self).create(vals) + + def set_to_sample_collection(self): + return self.write({'state': 'sample_collection'}) + + def set_to_test_in_progress(self): + return self.write({'state': 'test_in_progress'}) + + def cancel_lab_test(self): + return self.write({'state': 'cancel'}) + + def set_to_test_completed(self): + if not self.request_line: + raise ValidationError(_("No Result Lines Entered !")) + req_obj = self.env['lab.request'].search_count([('app_id', '=', self.app_id.id), + ('id', '!=', self.id)]) + req_obj_count = self.env['lab.request'].search_count([('app_id', '=', self.app_id.id), + ('id', '!=', self.id), + ('state', '=', 'completed')]) + if req_obj == req_obj_count: + app_obj = self.env['lab.appointment'].search([('id', '=', self.app_id.id)]) + app_obj.write({'state': 'completed'}) + return self.write({'state': 'completed'}) + + def print_lab_test(self): + return self.env.ref('medical_lab_management.print_lab_test').report_action(self) + + def lab_invoice_create(self): + invoice_obj = self.env["account.move"] + invoice_line_obj = self.env["account.move.line"] + for lab in self: + if lab.lab_requestor: + curr_invoice = { + 'partner_id': lab.lab_requestor.patient.id, + 'account_id': lab.lab_requestor.patient.property_account_receivable_id.id, + 'state': 'draft', + 'type': 'out_invoice', + 'date_invoice': datetime.datetime.now(), + 'origin': "Lab Test# : " + lab.name, + 'target': 'new', + 'lab_request': lab.id, + 'is_lab_invoice': True + } + + inv_ids = invoice_obj.create(curr_invoice) + inv_id = inv_ids.id + + if inv_ids: + journal = self.env['account.journal'].search([('type', '=', 'sale')], limit=1) + prd_account_id = journal.default_credit_account_id.id + if lab.test_request: + curr_invoice_line = { + 'name': "Charge for lab test", + 'price_unit': lab.test_request.test_cost or 0, + 'quantity': 1.0, + 'account_id': prd_account_id, + 'invoice_id': inv_id, + } + + invoice_line_obj.create(curr_invoice_line) + + self.write({'state': 'invoiced'}) + form_view_ref = self.env.ref('account.view_move_form', False) + tree_view_ref = self.env.ref('account.view_move_tree', False) + + return { + 'domain': "[('id', '=', " + str(inv_id) + ")]", + 'name': 'Lab Invoices', + 'view_mode': 'form', + 'res_model': 'account.move', + 'type': 'ir.actions.act_window', + 'views': [(tree_view_ref.id, 'tree'), (form_view_ref.id, 'form')], + } diff --git a/medical_lab_management/models/lab_test_content_type.py b/medical_lab_management/models/lab_test_content_type.py new file mode 100644 index 000000000..82b588d80 --- /dev/null +++ b/medical_lab_management/models/lab_test_content_type.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Anusha P P @ cybrosys and Niyas Raphy @ cybrosys(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 . +# +############################################################################# + +from odoo import models, fields + + +class LabTestContentType(models.Model): + _name = 'lab.test.content_type' + _rec_name = 'content_type_name' + _description = "Content" + + content_type_name = fields.Char(string="Name", required=True, help="Content type name") + content_type_code = fields.Char(string="Code") + parent_test = fields.Many2one('lab.test', string="Test Category") + + + + diff --git a/medical_lab_management/models/lab_test_type.py b/medical_lab_management/models/lab_test_type.py new file mode 100644 index 000000000..7f523477d --- /dev/null +++ b/medical_lab_management/models/lab_test_type.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Anusha P P @ cybrosys and Niyas Raphy @ cybrosys(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 . +# +############################################################################# + +from odoo import models, fields + + +class LabTestType(models.Model): + _name = 'lab.test' + _description = "Lab Test" + _rec_name = 'lab_test' + _inherit = ['mail.thread'] + + lab_test = fields.Char(string="Test Name", required=True, help="Name of lab test ") + lab_test_code = fields.Char(string="Test Code", required=True) + test_lines = fields.One2many('lab.test.attribute', 'test_line_reverse', string="Attribute") + test_cost = fields.Float(string="Cost", required=True) + + +class LabTestAttribute(models.Model): + _name = 'lab.test.attribute' + + test_content = fields.Many2one('lab.test.content_type', string="Content") + result = fields.Char(string="Result") + unit = fields.Many2one('test.unit', string="Unit") + interval = fields.Char(string="Reference Intervals") + test_line_reverse = fields.Many2one('lab.test', string="Attribute") + test_request_reverse = fields.Many2one('lab.request', string="Request") diff --git a/medical_lab_management/models/physician_speciality.py b/medical_lab_management/models/physician_speciality.py new file mode 100644 index 000000000..09a226902 --- /dev/null +++ b/medical_lab_management/models/physician_speciality.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Anusha P P @ cybrosys and Niyas Raphy @ cybrosys(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 . +# +############################################################################# + +from odoo import models, fields + + +class PhysicianSpeciality(models.Model): + _name = 'physician.speciality' + _description = 'Medical Specialty' + + code = fields.Char(string='ID') + name = fields.Char(string='Specialty', help='Name of the specialty', required=True) + + _sql_constraints = [ + ('name_uniq', 'UNIQUE(name)', 'Name must be unique!'), + ] diff --git a/medical_lab_management/models/res_partner.py b/medical_lab_management/models/res_partner.py new file mode 100644 index 000000000..0aa5803ca --- /dev/null +++ b/medical_lab_management/models/res_partner.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Anusha P P @ cybrosys and Niyas Raphy @ cybrosys(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 . +# +############################################################################# + +from odoo import models, fields + + +class ResPartnerPatient(models.Model): + _inherit = 'res.partner' + + is_patient = fields.Boolean(string='Is Patient') + is_physician = fields.Boolean(string='Is Physician') + speciality = fields.Many2one('physician.speciality', string='Speciality') + hospital = fields.Many2one('res.partner', string='Hospital') + + diff --git a/medical_lab_management/models/testing_unit.py b/medical_lab_management/models/testing_unit.py new file mode 100644 index 000000000..9855c4a47 --- /dev/null +++ b/medical_lab_management/models/testing_unit.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Anusha P P @ cybrosys and Niyas Raphy @ cybrosys(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 . +# +############################################################################# + +from odoo import models, fields + + +class TestingUnit(models.Model): + _name = 'test.unit' + _rec_name = 'code' + _description = "Test Unit" + + unit = fields.Char(string="Unit", required=True) + code = fields.Char(string="code", required=True) diff --git a/medical_lab_management/report/lab_patient_card.xml b/medical_lab_management/report/lab_patient_card.xml new file mode 100644 index 000000000..0d7686092 --- /dev/null +++ b/medical_lab_management/report/lab_patient_card.xml @@ -0,0 +1,63 @@ + + + + + + \ No newline at end of file diff --git a/medical_lab_management/report/lab_test_report.xml b/medical_lab_management/report/lab_test_report.xml new file mode 100644 index 000000000..0c2731485 --- /dev/null +++ b/medical_lab_management/report/lab_test_report.xml @@ -0,0 +1,50 @@ + + + + + + + diff --git a/medical_lab_management/report/report.xml b/medical_lab_management/report/report.xml new file mode 100644 index 000000000..6e1ef248b --- /dev/null +++ b/medical_lab_management/report/report.xml @@ -0,0 +1,32 @@ + + + + + Lab Test Result + lab.request + qweb-pdf + medical_lab_management.report_patient_labtest + medical_lab_management.report_patient_labtest + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/medical_lab_management/security/ir.model.access.csv b/medical_lab_management/security/ir.model.access.csv new file mode 100644 index 000000000..d694f8b26 --- /dev/null +++ b/medical_lab_management/security/ir.model.access.csv @@ -0,0 +1,19 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_lab_request_user,lab.request,model_lab_request,group_lab_management_user,1,1,1,1 +access_lab_patient_user,lab.patient,model_lab_patient,group_lab_management_user,1,1,1,1 +access_lab_appointment_user,lab.appointment,model_lab_appointment,group_lab_management_user,1,1,1,1 +access_test_unit_user,test.unit,model_test_unit,group_lab_management_user,1,0,0,0 +access_lab_physician_user,physician.speciality,model_physician_speciality,group_lab_management_user,1,1,1,1 +access_lab_test_user,lab.test,model_lab_test,group_lab_management_user,1,0,0,0 +access_lab_appointment_line_user,lab.appointment.lines,model_lab_appointment_lines,group_lab_management_user,1,1,1,1 +access_lab_test_content_type_user,lab.test.content_type,model_lab_test_content_type,group_lab_management_user,1,0,0,0 +access_lab_test_attribute_user,lab.test.attribute,model_lab_test_attribute,group_lab_management_user,1,1,1,1 +access_lab_request_technician,lab.request,model_lab_request,group_lab_management_technician,1,1,1,1 +access_lab_patient_technician,lab.patient,model_lab_patient,group_lab_management_technician,1,1,1,1 +access_lab_appointment_technician,lab.appointment,model_lab_appointment,group_lab_management_technician,1,1,1,1 +access_test_unit_technician,test.unit,model_test_unit,group_lab_management_technician,1,1,1,1 +access_lab_physician_technician,physician.speciality,model_physician_speciality,group_lab_management_technician,1,0,0,0 +access_lab_test_technician,lab.test,model_lab_test,group_lab_management_technician,1,1,1,1 +access_lab_test_content_type_technician,lab.test.content_type,model_lab_test_content_type,group_lab_management_technician,1,1,1,1 +access_lab_appointment_line_technician,lab.appointment.lines,model_lab_appointment_lines,group_lab_management_technician,1,1,1,1 +access_lab_test_attribute_technician,lab.test.attribute,model_lab_test_attribute,group_lab_management_technician,1,1,1,1 \ No newline at end of file diff --git a/medical_lab_management/security/lab_users.xml b/medical_lab_management/security/lab_users.xml new file mode 100644 index 000000000..28cf8cee3 --- /dev/null +++ b/medical_lab_management/security/lab_users.xml @@ -0,0 +1,20 @@ + + + + Lab Management + + + + Lab User + + + + + + Lab Manager + + + + + + \ No newline at end of file diff --git a/medical_lab_management/static/description/banner.png b/medical_lab_management/static/description/banner.png new file mode 100644 index 000000000..205464294 Binary files /dev/null and b/medical_lab_management/static/description/banner.png differ diff --git a/medical_lab_management/static/description/icon.png b/medical_lab_management/static/description/icon.png new file mode 100644 index 000000000..83dc6820b Binary files /dev/null and b/medical_lab_management/static/description/icon.png differ diff --git a/medical_lab_management/static/description/images/appointment3.png b/medical_lab_management/static/description/images/appointment3.png new file mode 100644 index 000000000..acf9fd8c8 Binary files /dev/null and b/medical_lab_management/static/description/images/appointment3.png differ diff --git a/medical_lab_management/static/description/images/banner_lifeline_for_task.jpeg b/medical_lab_management/static/description/images/banner_lifeline_for_task.jpeg new file mode 100644 index 000000000..4a467ea22 Binary files /dev/null and b/medical_lab_management/static/description/images/banner_lifeline_for_task.jpeg differ diff --git a/medical_lab_management/static/description/images/banner_project_report_xls_pdf.png b/medical_lab_management/static/description/images/banner_project_report_xls_pdf.png new file mode 100644 index 000000000..3c430a7eb Binary files /dev/null and b/medical_lab_management/static/description/images/banner_project_report_xls_pdf.png differ diff --git a/medical_lab_management/static/description/images/banner_project_status_report.png b/medical_lab_management/static/description/images/banner_project_status_report.png new file mode 100644 index 000000000..d1b689710 Binary files /dev/null and b/medical_lab_management/static/description/images/banner_project_status_report.png differ diff --git a/medical_lab_management/static/description/images/banner_subtask.jpeg b/medical_lab_management/static/description/images/banner_subtask.jpeg new file mode 100644 index 000000000..f2b224110 Binary files /dev/null and b/medical_lab_management/static/description/images/banner_subtask.jpeg differ diff --git a/medical_lab_management/static/description/images/banner_task_deadline_reminder.jpeg b/medical_lab_management/static/description/images/banner_task_deadline_reminder.jpeg new file mode 100644 index 000000000..998679818 Binary files /dev/null and b/medical_lab_management/static/description/images/banner_task_deadline_reminder.jpeg differ diff --git a/medical_lab_management/static/description/images/banner_task_statusbar.jpeg b/medical_lab_management/static/description/images/banner_task_statusbar.jpeg new file mode 100644 index 000000000..2c57cbb7b Binary files /dev/null and b/medical_lab_management/static/description/images/banner_task_statusbar.jpeg differ diff --git a/medical_lab_management/static/description/images/checked.png b/medical_lab_management/static/description/images/checked.png new file mode 100644 index 000000000..578cedb80 Binary files /dev/null and b/medical_lab_management/static/description/images/checked.png differ diff --git a/medical_lab_management/static/description/images/cr_patient1.png b/medical_lab_management/static/description/images/cr_patient1.png new file mode 100644 index 000000000..02fa5c634 Binary files /dev/null and b/medical_lab_management/static/description/images/cr_patient1.png differ diff --git a/medical_lab_management/static/description/images/cybrosys.png b/medical_lab_management/static/description/images/cybrosys.png new file mode 100644 index 000000000..d76b5bafb Binary files /dev/null and b/medical_lab_management/static/description/images/cybrosys.png differ diff --git a/medical_lab_management/static/description/images/draft invoice7.png b/medical_lab_management/static/description/images/draft invoice7.png new file mode 100644 index 000000000..d19ab47af Binary files /dev/null and b/medical_lab_management/static/description/images/draft invoice7.png differ diff --git a/medical_lab_management/static/description/images/l1.png b/medical_lab_management/static/description/images/l1.png new file mode 100644 index 000000000..5268e7ad9 Binary files /dev/null and b/medical_lab_management/static/description/images/l1.png differ diff --git a/medical_lab_management/static/description/images/lab report6.png b/medical_lab_management/static/description/images/lab report6.png new file mode 100644 index 000000000..9102df29f Binary files /dev/null and b/medical_lab_management/static/description/images/lab report6.png differ diff --git a/medical_lab_management/static/description/images/lab test9.png b/medical_lab_management/static/description/images/lab test9.png new file mode 100644 index 000000000..88173c691 Binary files /dev/null and b/medical_lab_management/static/description/images/lab test9.png differ diff --git a/medical_lab_management/static/description/images/lab user1.png b/medical_lab_management/static/description/images/lab user1.png new file mode 100644 index 000000000..6ff00785e Binary files /dev/null and b/medical_lab_management/static/description/images/lab user1.png differ diff --git a/medical_lab_management/static/description/images/lab user2.png b/medical_lab_management/static/description/images/lab user2.png new file mode 100644 index 000000000..11b979032 Binary files /dev/null and b/medical_lab_management/static/description/images/lab user2.png differ diff --git a/medical_lab_management/static/description/images/lab_request5.png b/medical_lab_management/static/description/images/lab_request5.png new file mode 100644 index 000000000..3206a27f1 Binary files /dev/null and b/medical_lab_management/static/description/images/lab_request5.png differ diff --git a/medical_lab_management/static/description/images/mail.png b/medical_lab_management/static/description/images/mail.png new file mode 100644 index 000000000..cc9ae70c8 Binary files /dev/null and b/medical_lab_management/static/description/images/mail.png differ diff --git a/medical_lab_management/static/description/images/patient_card2.png b/medical_lab_management/static/description/images/patient_card2.png new file mode 100644 index 000000000..321f3ab5d Binary files /dev/null and b/medical_lab_management/static/description/images/patient_card2.png differ diff --git a/medical_lab_management/static/description/images/physician12.png b/medical_lab_management/static/description/images/physician12.png new file mode 100644 index 000000000..ca61123d5 Binary files /dev/null and b/medical_lab_management/static/description/images/physician12.png differ diff --git a/medical_lab_management/static/description/images/test content10.png b/medical_lab_management/static/description/images/test content10.png new file mode 100644 index 000000000..947ce13db Binary files /dev/null and b/medical_lab_management/static/description/images/test content10.png differ diff --git a/medical_lab_management/static/description/images/testing unit11.png b/medical_lab_management/static/description/images/testing unit11.png new file mode 100644 index 000000000..d75bf01aa Binary files /dev/null and b/medical_lab_management/static/description/images/testing unit11.png differ diff --git a/medical_lab_management/static/description/images/today appo8.png b/medical_lab_management/static/description/images/today appo8.png new file mode 100644 index 000000000..d3bcd490a Binary files /dev/null and b/medical_lab_management/static/description/images/today appo8.png differ diff --git a/medical_lab_management/static/description/index.html b/medical_lab_management/static/description/index.html new file mode 100644 index 000000000..0ce794f0b --- /dev/null +++ b/medical_lab_management/static/description/index.html @@ -0,0 +1,393 @@ +
cybrosys-logo
+
+
+
+

Medical Lab Management

+

Manage Lab Activities

+
+

Key Highlights

+
    +
  • Manage Patients
  • +
  • Issue Patient Card
  • +
  • Manage Referrals of Patients
  • +
  • Manage Appointments
  • +
  • Mail Notification For Appointments
  • +
  • Manage Lab Requests
  • +
  • Print Lab Test Result Of Patient
  • + +
+
+
+
+ +
+
+
+
+ +
+
+ +

Overview

+
+

+ This app helps the user to systematically perform the activities of a Medical Laboratory. The app simplifies the activities like Patient Management, Appointment Management, Test Requests Management, Lab Results Management, and so on.

+
+
+ +

Medical Lab Management

+
+
    +
  • + Manage Patients +
  • + +
  • + Issue Patient Card +
  • + +
  • + Manage Referrals of Patients +
  • + +
  • + Manage Appointments +
  • + +
  • + Mail Notification For Appointments +
  • + +
  • + Manage Lab Requests +
  • + + +
  • + Print Lab Test Result Of Patient +
  • +
+
+ +
+
+

Screenshots

+
+
+
+ +
+
+
+
+ + +
+
    +
+
+
+
+
+
+
+

Suggested Products

+
+ +
+
+

Our Service

+
+ +
+
+
+

Our Industries

+
+ +
+
+
+ +
+
+

Trading

+

Easily procure and sell your products.

+
+
+
+
+ +
+
+

Manufacturing

+

Plan, track and schedule your operations.

+
+
+
+
+ +
+
+

Restaurant

+

Run your bar or restaurant methodical.

+
+
+
+
+ +
+
+

POS

+

Easy configuring and convivial selling.

+
+
+
+
+ +
+
+

E-commerce & Website

+

Mobile friendly, awe-inspiring product pages.

+
+
+
+
+ +
+
+

Hotel Management

+

An all-inclusive hotel management application.

+
+
+
+
+ +
+
+

Education

+

A Collaborative platform for educational management.

+
+
+
+
+ +
+
+

Service Management

+

Keep track of services and invoice accordingly.

+
+
+
+
+
+ +
+
+
+

Need Any Help?

+
+

If you have anything to share with us based on your use of this module, please let us know. We are ready to offer our support.

+
+

Email us

+

odoo@cybrosys.com / info@cybrosys.com

+
+
+

Contact Us

+ www.cybrosys.com +
+
+
+
+
+
+
+
+
+ +
+ + + + + + + +
+
+
+ \ No newline at end of file diff --git a/medical_lab_management/views/account_invoice.xml b/medical_lab_management/views/account_invoice.xml new file mode 100644 index 000000000..167560a3e --- /dev/null +++ b/medical_lab_management/views/account_invoice.xml @@ -0,0 +1,30 @@ + + + + + account.invoice.cust.invoice_form + account.move + + + + + + + + + + + account.invoice.cust.invoice_filter_form + account.move + + + + + + + + + + + + \ No newline at end of file diff --git a/medical_lab_management/views/lab_appointment.xml b/medical_lab_management/views/lab_appointment.xml new file mode 100644 index 000000000..8bcbe2878 --- /dev/null +++ b/medical_lab_management/views/lab_appointment.xml @@ -0,0 +1,231 @@ + + + + + Invoices + account.move + tree,form,kanban,graph,pivot + + [('is_lab_invoice','=',True)] + + +

+ Create Invoices. +

+
+
+ + + 1 + tree + + + + + 2 + form + + + + + + Appointment Kanban + lab.appointment + + + + +
+
+ +
    +
  • Name :
  • +
  • Lab Request ID :
  • +
  • Appointment Date :
  • +
+
+
+
+
+
+
+
+
+ + + lab.appointment.tree + lab.appointment + + + + + + + + + + + + lab.appointment.form + lab.appointment + + +
+
+
+ +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+
+
+ + + lab.appointment.search + lab.appointment + + + + + + + + + + + + + + + + + + + + Appointments + ir.actions.act_window + lab.appointment + tree,form,kanban + + [] + {} + +

+ Create Appointments. +

+
+
+ + + + Appointments + ir.actions.act_window + lab.appointment + tree,form + + [('appointment_date', '>=',((datetime.date.today()- datetime.timedelta(days=0)).strftime('%Y-%m-%d 00:00:00'))), + ('appointment_date', '<=',((datetime.date.today()- datetime.timedelta(days=0)).strftime('%Y-%m-%d 23:59:59')))] + + {} + +

+ Create Appointments. +

+
+
+ + + Appointment + lab.appointment + ID + 3 + + + + + + + + + + + lab.patient.form + lab.patient + + + + + + + + + +
+
diff --git a/medical_lab_management/views/lab_patient_view.xml b/medical_lab_management/views/lab_patient_view.xml new file mode 100644 index 000000000..2aba9ee9f --- /dev/null +++ b/medical_lab_management/views/lab_patient_view.xml @@ -0,0 +1,159 @@ + + + + + + Patient Kanban + lab.patient + + + + + +
+
+ +
+
+ +
    +
  • Name :
  • +
  • Patient ID :
  • +
+
+
+
+
+
+
+
+
+ + + lab.patient.tree + lab.patient + + + + + + + + + + + + + + lab.patient.form + lab.patient + + +
+ +
+
+ +
+

+ +

+

+ + + + +
+ +
+

+
+ + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + lab.patient.search + lab.patient + + + + + + + + + + + + + + + + + + Patients + ir.actions.act_window + lab.patient + kanban,tree,form + + [] + {} + +

+ Create Patients. +

+
+
+ + + Patient + lab.patient + PID + 3 + + + + + + + +
+
diff --git a/medical_lab_management/views/lab_request.xml b/medical_lab_management/views/lab_request.xml new file mode 100644 index 000000000..ad9ace78f --- /dev/null +++ b/medical_lab_management/views/lab_request.xml @@ -0,0 +1,120 @@ + + + + + lab.request.tree + lab.request + + + + + + + + + + + + lab.request.form + lab.request + +
+
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+
+
+ + lab.request.search + lab.request + + + + + + + + + + + + + + + + + Lab Request + ir.actions.act_window + lab.request + tree,form + + [] + {} + +

+ Create Lab request. +

+
+
+ + + Lab Request + lab.request + LR + 3 + + + + + +
+
diff --git a/medical_lab_management/views/lab_test_content_type.xml b/medical_lab_management/views/lab_test_content_type.xml new file mode 100644 index 000000000..5424b026e --- /dev/null +++ b/medical_lab_management/views/lab_test_content_type.xml @@ -0,0 +1,72 @@ + + + + + lab.test.content_type.tree + lab.test.content_type + + + + + + + + + + + lab.test.content_type.form + lab.test.content_type + + +
+ + + + + + + + +
+
+
+ + + lab.test.content_type.search + lab.test.content_type + + + + + + + + + + + + + + + + Test Contents + ir.actions.act_window + lab.test.content_type + tree,form + [] + + {} + +

+ Create Test Contents. +

+
+
+ + +
+
diff --git a/medical_lab_management/views/lab_test_type.xml b/medical_lab_management/views/lab_test_type.xml new file mode 100644 index 000000000..41be81746 --- /dev/null +++ b/medical_lab_management/views/lab_test_type.xml @@ -0,0 +1,102 @@ + + + + + lab.test.tree + lab.test + + + + + + + + + + + + lab.test.form + lab.test + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + lab.test.search + lab.test + + + + + + + + + + + + + + Lab Test + ir.actions.act_window + lab.test + tree,form + + [] + {} + +

+ Create Lab Tests. +

+
+
+ + + + + lab.test.attribute.form + lab.test.attribute + + +
+ + + + + + + + +
+
+
+
+
\ No newline at end of file diff --git a/medical_lab_management/views/physician_details.xml b/medical_lab_management/views/physician_details.xml new file mode 100644 index 000000000..93ba3e1a4 --- /dev/null +++ b/medical_lab_management/views/physician_details.xml @@ -0,0 +1,26 @@ + + + + + Physician + ir.actions.act_window + res.partner + tree,form + [('is_physician','=',1)] + {'default_customer':0, 'default_supplier':0 , 'default_is_physician':1} + + +

+ Click to add physician. +

+
+
+ + + +
+
diff --git a/medical_lab_management/views/physician_specialty.xml b/medical_lab_management/views/physician_specialty.xml new file mode 100644 index 000000000..a3d5e680c --- /dev/null +++ b/medical_lab_management/views/physician_specialty.xml @@ -0,0 +1,18 @@ + + + + + physician.speciality.form + physician.speciality + + +
+ + + + +
+
+
+
+
diff --git a/medical_lab_management/views/res_partner.xml b/medical_lab_management/views/res_partner.xml new file mode 100644 index 000000000..3981f0155 --- /dev/null +++ b/medical_lab_management/views/res_partner.xml @@ -0,0 +1,22 @@ + + + + + res.partner.form + res.partner + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/medical_lab_management/views/test_unit_view.xml b/medical_lab_management/views/test_unit_view.xml new file mode 100644 index 000000000..0d6e6fa69 --- /dev/null +++ b/medical_lab_management/views/test_unit_view.xml @@ -0,0 +1,71 @@ + + + + + test.unit.tree + test.unit + + + + + + + + + + test.unit.form + test.unit + + +
+ + + + + + + + + + +
+
+
+ + test.unit.search + test.unit + + + + + + + + + + + + Testing Units + ir.actions.act_window + test.unit + tree,form + + [] + {} + +

+ Create Testing Units. +

+
+
+ + +
+
\ No newline at end of file diff --git a/sale_discount_total/README.rst b/sale_discount_total/README.rst new file mode 100644 index 000000000..9e480e4b6 --- /dev/null +++ b/sale_discount_total/README.rst @@ -0,0 +1,40 @@ +Sale Discount on Total Amount +============================= +Discount on Total in Sale and Invoice With Discount Limit and Approval + +Configuration +============= +* No additional configurations needed + +Company +------- +* `Cybrosys Techno Solutions `__ + +Credits +------- +* Developer: Faslu Rahman@cybrosys + V14: Muhammed P@cybrosys + +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 `__ + +Further information +=================== +HTML Description: ``__ + + diff --git a/sale_discount_total/__init__.py b/sale_discount_total/__init__.py new file mode 100644 index 000000000..f53800003 --- /dev/null +++ b/sale_discount_total/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Faslu Rahman(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 . +# +############################################################################# +from . import models +from . import reports + diff --git a/sale_discount_total/__manifest__.py b/sale_discount_total/__manifest__.py new file mode 100644 index 000000000..2589239f7 --- /dev/null +++ b/sale_discount_total/__manifest__.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2020-TODAY Cybrosys Technologies(). +# Author: Faslu Rahman(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 . +# +############################################################################# + +{ + 'name': 'Sale Discount on Total Amount', + 'version': '14.0.1.0.0', + 'category': 'Sales Management', + 'summary': "Discount on Total in Sale and Invoice With Discount Limit and Approval", + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'website': 'http://www.cybrosys.com', + 'description': """ + +Sale Discount for Total Amount +======================= +Module to manage discount on total amount in Sale. + as an specific amount or percentage +""", + 'depends': ['sale', + 'account', 'delivery' + ], + 'data': [ + 'views/sale_view.xml', + 'views/account_invoice_view.xml', + 'views/invoice_report.xml', + 'views/sale_order_report.xml', + 'views/res_config_view.xml', + + ], + 'images': ['static/description/banner.png'], + 'license': 'AGPL-3', + 'application': True, + 'installable': True, + 'auto_install': False, +} diff --git a/sale_discount_total/doc/RELEASE_NOTES.md b/sale_discount_total/doc/RELEASE_NOTES.md new file mode 100644 index 000000000..0bb516ee6 --- /dev/null +++ b/sale_discount_total/doc/RELEASE_NOTES.md @@ -0,0 +1,9 @@ +## Module + +#### 08.10.2020 +#### Version 14.0.1.0.0 +#### ADD +Initial commit for Sale Discount On Total Amount + + + diff --git a/sale_discount_total/models/__init__.py b/sale_discount_total/models/__init__.py new file mode 100644 index 000000000..695e03083 --- /dev/null +++ b/sale_discount_total/models/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Faslu Rahman(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 . +# +############################################################################# +from . import sale +from . import account_invoice +from . import discount_approval + diff --git a/sale_discount_total/models/account_invoice.py b/sale_discount_total/models/account_invoice.py new file mode 100644 index 000000000..971600e3b --- /dev/null +++ b/sale_discount_total/models/account_invoice.py @@ -0,0 +1,176 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Faslu Rahman(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 . +# +############################################################################# + +from odoo import api, fields, models + + +class AccountInvoice(models.Model): + _inherit = "account.move" + + @api.depends( + 'line_ids.matched_debit_ids.debit_move_id.move_id.line_ids.amount_residual', + 'line_ids.matched_debit_ids.debit_move_id.move_id.line_ids.amount_residual_currency', + 'line_ids.matched_credit_ids.credit_move_id.move_id.line_ids.amount_residual', + 'line_ids.matched_credit_ids.credit_move_id.move_id.line_ids.amount_residual_currency', + 'line_ids.debit', + 'line_ids.credit', + 'line_ids.currency_id', + 'line_ids.amount_currency', + 'line_ids.amount_residual', + 'line_ids.amount_residual_currency', + 'line_ids.payment_id.state', + 'line_ids.full_reconcile_id') + def _compute_amount(self): + for move in self: + + if move.payment_state == 'invoicing_legacy': + # invoicing_legacy state is set via SQL when setting setting field + # invoicing_switch_threshold (defined in account_accountant). + # The only way of going out of this state is through this setting, + # so we don't recompute it here. + move.payment_state = move.payment_state + continue + + total_untaxed = 0.0 + total_untaxed_currency = 0.0 + total_tax = 0.0 + total_tax_currency = 0.0 + total_to_pay = 0.0 + total_residual = 0.0 + total_residual_currency = 0.0 + total = 0.0 + total_currency = 0.0 + currencies = set() + + for line in move.line_ids: + if line.currency_id: + currencies.add(line.currency_id) + + if move.is_invoice(include_receipts=True): + # === Invoices === + + if not line.exclude_from_invoice_tab: + # Untaxed amount. + total_untaxed += line.balance + total_untaxed_currency += line.amount_currency + total += line.balance + total_currency += line.amount_currency + elif line.tax_line_id: + # Tax amount. + total_tax += line.balance + total_tax_currency += line.amount_currency + total += line.balance + total_currency += line.amount_currency + elif line.account_id.user_type_id.type in ('receivable', 'payable'): + # Residual amount. + total_to_pay += line.balance + total_residual += line.amount_residual + total_residual_currency += line.amount_residual_currency + else: + # === Miscellaneous journal entry === + if line.debit: + total += line.balance + total_currency += line.amount_currency + + if move.move_type == 'entry' or move.is_outbound(): + sign = 1 + else: + sign = -1 + if move.discount_type == 'percent': + move.amount_discount = sum((line.quantity * line.price_unit * line.discount) / 100 for line in move.invoice_line_ids) + else: + move.amount_discount = move.discount_rate + move.amount_untaxed = sign * (total_untaxed_currency if len(currencies) == 1 else total_untaxed) + move.amount_tax = sign * (total_tax_currency if len(currencies) == 1 else total_tax) + move.amount_total = sign * (total_currency if len(currencies) == 1 else total) + move.amount_residual = -sign * (total_residual_currency if len(currencies) == 1 else total_residual) + move.amount_untaxed_signed = -total_untaxed + move.amount_tax_signed = -total_tax + move.amount_total_signed = abs(total) if move.move_type == 'entry' else -total + move.amount_residual_signed = total_residual + + currency = len(currencies) == 1 and currencies.pop() or move.company_id.currency_id + + # Compute 'payment_state'. + new_pmt_state = 'not_paid' if move.move_type != 'entry' else False + + if move.is_invoice(include_receipts=True) and move.state == 'posted': + + if currency.is_zero(move.amount_residual): + if all(payment.is_matched for payment in move._get_reconciled_payments()): + new_pmt_state = 'paid' + else: + new_pmt_state = move._get_invoice_in_payment_state() + elif currency.compare_amounts(total_to_pay, total_residual) != 0: + new_pmt_state = 'partial' + + if new_pmt_state == 'paid' and move.move_type in ('in_invoice', 'out_invoice', 'entry'): + reverse_type = move.move_type == 'in_invoice' and 'in_refund' or move.move_type == 'out_invoice' and 'out_refund' or 'entry' + reverse_moves = self.env['account.move'].search( + [('reversed_entry_id', '=', move.id), ('state', '=', 'posted'), ('move_type', '=', reverse_type)]) + + # We only set 'reversed' state in cas of 1 to 1 full reconciliation with a reverse entry; otherwise, we use the regular 'paid' state + reverse_moves_full_recs = reverse_moves.mapped('line_ids.full_reconcile_id') + if reverse_moves_full_recs.mapped('reconciled_line_ids.move_id').filtered(lambda x: x not in ( + reverse_moves + reverse_moves_full_recs.mapped('exchange_move_id'))) == move: + new_pmt_state = 'reversed' + + move.payment_state = new_pmt_state + + discount_type = fields.Selection([('percent', 'Percentage'), ('amount', 'Amount')], string='Discount Type', + readonly=True, states={'draft': [('readonly', False)]}, default='percent') + discount_rate = fields.Float('Discount Amount', digits=(16, 2), readonly=True, + states={'draft': [('readonly', False)]}) + amount_discount = fields.Monetary(string='Discount', store=True, readonly=True, compute='_compute_amount', + track_visibility='always') + + @api.onchange('discount_type', 'discount_rate', 'invoice_line_ids') + def supply_rate(self): + for inv in self: + if inv.discount_type == 'percent': + for line in inv.line_ids: + line.discount = inv.discount_rate + line._onchange_price_subtotal() + else: + total = discount = 0.0 + for line in inv.invoice_line_ids: + total += (line.quantity * line.price_unit) + if inv.discount_rate != 0: + discount = (inv.discount_rate / total) * 100 + else: + discount = inv.discount_rate + for line in inv.line_ids: + line.discount = discount + line._onchange_price_subtotal() + + inv._compute_invoice_taxes_by_group() + # + + def button_dummy(self): + self.supply_rate() + return True + + +class AccountInvoiceLine(models.Model): + _inherit = "account.move.line" + + discount = fields.Float(string='Discount (%)', digits=(16, 20), default=0.0) diff --git a/sale_discount_total/models/discount_approval.py b/sale_discount_total/models/discount_approval.py new file mode 100644 index 000000000..160d6ecb4 --- /dev/null +++ b/sale_discount_total/models/discount_approval.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Faslu Rahman(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 . +# +############################################################################# + +from odoo import api, fields, models + + +class sale_discount(models.Model): + _inherit = 'sale.order' + + state = fields.Selection([ + ('draft', 'Quotation'), + ('sent', 'Quotation Sent'), + ('waiting', 'Waiting Approval'), + ('sale', 'Sales Order'), + ('done', 'Locked'), + ('cancel', 'Cancelled'), + ], string='Status', readonly=True, copy=False, index=True, track_visibility='onchange', default='draft') + + + def action_confirm(self): + discnt = 0.0 + no_line = 0.0 + if self.company_id.so_double_validation == 'two_step': + for line in self.order_line: + no_line += 1 + discnt += line.discount + discnt = (discnt / no_line) + if self.company_id.so_double_validation_limit and discnt > self.company_id.so_double_validation_limit: + self.state = 'waiting' + return True + super(sale_discount, self).action_confirm() + + + def action_approve(self): + super(sale_discount, self).action_confirm() + return True + + +class Company(models.Model): + _inherit = 'res.company' + + so_double_validation = fields.Selection([ + ('one_step', 'Confirm sale orders in one step'), + ('two_step', 'Get 2 levels of approvals to confirm a sale order') + ], string="Levels of Approvals", default='one_step', + help="Provide a double validation mechanism for sales discount") + + so_double_validation_limit = fields.Float(string="Percentage of Discount that requires double validation'", + help="Minimum discount percentage for which a double validation is required") + + +class ResDiscountSettings(models.TransientModel): + _inherit = 'res.config.settings' + + so_order_approval = fields.Boolean("Sale Discount Approval", default=lambda self: self.env.user.company_id.so_double_validation == 'two_step') + + so_double_validation = fields.Selection(related='company_id.so_double_validation',string="Levels of Approvals *", readonly=False) + so_double_validation_limit = fields.Float(string="Discount limit requires approval in %", + related='company_id.so_double_validation_limit', readonly=False) + + def set_values(self): + super(ResDiscountSettings, self).set_values() + self.so_double_validation = 'two_step' if self.so_order_approval else 'one_step' diff --git a/sale_discount_total/models/sale.py b/sale_discount_total/models/sale.py new file mode 100644 index 000000000..76cbc8cf5 --- /dev/null +++ b/sale_discount_total/models/sale.py @@ -0,0 +1,98 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Faslu Rahman(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 . +# +############################################################################# + +from odoo import api, fields, models +import odoo.addons.decimal_precision as dp + + +class SaleOrder(models.Model): + _inherit = "sale.order" + + @api.depends('order_line.price_total') + def _amount_all(self): + """ + Compute the total amounts of the SO. + """ + for order in self: + amount_untaxed = amount_tax = amount_discount = 0.0 + for line in order.order_line: + amount_untaxed += line.price_subtotal + amount_tax += line.price_tax + amount_discount += (line.product_uom_qty * line.price_unit * line.discount) / 100 + order.update({ + 'amount_untaxed': amount_untaxed, + 'amount_tax': amount_tax, + 'amount_discount': amount_discount, + 'amount_total': amount_untaxed + amount_tax, + }) + + discount_type = fields.Selection([('percent', 'Percentage'), ('amount', 'Amount')], string='Discount type', + readonly=True, + states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, + default='percent') + discount_rate = fields.Float('Discount Rate', digits=dp.get_precision('Account'), + readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}) + amount_untaxed = fields.Monetary(string='Untaxed Amount', store=True, readonly=True, compute='_amount_all', + track_visibility='always') + amount_tax = fields.Monetary(string='Taxes', store=True, readonly=True, compute='_amount_all', + track_visibility='always') + amount_total = fields.Monetary(string='Total', store=True, readonly=True, compute='_amount_all', + track_visibility='always') + amount_discount = fields.Monetary(string='Discount', store=True, readonly=True, compute='_amount_all', + digits=dp.get_precision('Account'), track_visibility='always') + + @api.onchange('discount_type', 'discount_rate', 'order_line') + def supply_rate(self): + + for order in self: + if order.discount_type == 'percent': + for line in order.order_line: + line.discount = order.discount_rate + else: + total = discount = 0.0 + for line in order.order_line: + total += round((line.product_uom_qty * line.price_unit)) + if order.discount_rate != 0: + discount = (order.discount_rate / total) * 100 + else: + discount = order.discount_rate + for line in order.order_line: + line.discount = discount + + def _prepare_invoice(self, ): + invoice_vals = super(SaleOrder, self)._prepare_invoice() + invoice_vals.update({ + 'discount_type': self.discount_type, + 'discount_rate': self.discount_rate, + }) + return invoice_vals + + def button_dummy(self): + + self.supply_rate() + return True + + +class SaleOrderLine(models.Model): + _inherit = "sale.order.line" + + discount = fields.Float(string='Discount (%)', digits=(16, 20), default=0.0) diff --git a/sale_discount_total/reports/__init__.py b/sale_discount_total/reports/__init__.py new file mode 100644 index 000000000..119231c54 --- /dev/null +++ b/sale_discount_total/reports/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Faslu Rahman(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 . +# +############################################################################# +from . import invoice_report +from . import sale_report diff --git a/sale_discount_total/reports/invoice_report.py b/sale_discount_total/reports/invoice_report.py new file mode 100644 index 000000000..17c1b865c --- /dev/null +++ b/sale_discount_total/reports/invoice_report.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Faslu Rahman(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 . +# +############################################################################# + +from odoo import fields, models + + +class AccountInvoiceReport(models.Model): + _inherit = 'account.invoice.report' + + discount = fields.Float('Discount', readonly=True) + + def _select(self): + res = super(AccountInvoiceReport,self)._select() + select_str = res + """, line.discount AS discount """ + return select_str + diff --git a/sale_discount_total/reports/sale_report.py b/sale_discount_total/reports/sale_report.py new file mode 100644 index 000000000..a9b9a4451 --- /dev/null +++ b/sale_discount_total/reports/sale_report.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author: Faslu Rahman(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 . +# +############################################################################# + + +from odoo import fields, models + + +class DiscountSaleReport(models.Model): + _inherit = 'sale.report' + + discount = fields.Float('Discount', readonly=True) + + def _select(self): + res = super(DiscountSaleReport,self)._select() + select_str = res+""",sum(l.product_uom_qty / u.factor * u2.factor * cr.rate * l.price_unit * l.discount / 100.0) + as discount""" + return select_str diff --git a/sale_discount_total/static/description/benner.png b/sale_discount_total/static/description/benner.png new file mode 100644 index 000000000..009c6004b Binary files /dev/null and b/sale_discount_total/static/description/benner.png differ diff --git a/sale_discount_total/static/description/cybro_logo.png b/sale_discount_total/static/description/cybro_logo.png new file mode 100644 index 000000000..bb309114c Binary files /dev/null and b/sale_discount_total/static/description/cybro_logo.png differ diff --git a/sale_discount_total/static/description/icon.png b/sale_discount_total/static/description/icon.png new file mode 100644 index 000000000..fa33d5755 Binary files /dev/null and b/sale_discount_total/static/description/icon.png differ diff --git a/sale_discount_total/static/description/images/approval.png b/sale_discount_total/static/description/images/approval.png new file mode 100644 index 000000000..846d5b0c9 Binary files /dev/null and b/sale_discount_total/static/description/images/approval.png differ diff --git a/sale_discount_total/static/description/images/banner_lifeline_for_task.jpeg b/sale_discount_total/static/description/images/banner_lifeline_for_task.jpeg new file mode 100644 index 000000000..4a467ea22 Binary files /dev/null and b/sale_discount_total/static/description/images/banner_lifeline_for_task.jpeg differ diff --git a/sale_discount_total/static/description/images/banner_project_report_xls_pdf.png b/sale_discount_total/static/description/images/banner_project_report_xls_pdf.png new file mode 100644 index 000000000..3c430a7eb Binary files /dev/null and b/sale_discount_total/static/description/images/banner_project_report_xls_pdf.png differ diff --git a/sale_discount_total/static/description/images/banner_project_status_report.png b/sale_discount_total/static/description/images/banner_project_status_report.png new file mode 100644 index 000000000..d1b689710 Binary files /dev/null and b/sale_discount_total/static/description/images/banner_project_status_report.png differ diff --git a/sale_discount_total/static/description/images/banner_subtask.jpeg b/sale_discount_total/static/description/images/banner_subtask.jpeg new file mode 100644 index 000000000..f2b224110 Binary files /dev/null and b/sale_discount_total/static/description/images/banner_subtask.jpeg differ diff --git a/sale_discount_total/static/description/images/banner_task_deadline_reminder.jpeg b/sale_discount_total/static/description/images/banner_task_deadline_reminder.jpeg new file mode 100644 index 000000000..998679818 Binary files /dev/null and b/sale_discount_total/static/description/images/banner_task_deadline_reminder.jpeg differ diff --git a/sale_discount_total/static/description/images/banner_task_statusbar.jpeg b/sale_discount_total/static/description/images/banner_task_statusbar.jpeg new file mode 100644 index 000000000..2c57cbb7b Binary files /dev/null and b/sale_discount_total/static/description/images/banner_task_statusbar.jpeg differ diff --git a/sale_discount_total/static/description/images/checked.png b/sale_discount_total/static/description/images/checked.png new file mode 100644 index 000000000..578cedb80 Binary files /dev/null and b/sale_discount_total/static/description/images/checked.png differ diff --git a/sale_discount_total/static/description/images/customer invoice.png b/sale_discount_total/static/description/images/customer invoice.png new file mode 100644 index 000000000..83096c29d Binary files /dev/null and b/sale_discount_total/static/description/images/customer invoice.png differ diff --git a/sale_discount_total/static/description/images/customer _invoice-1.png b/sale_discount_total/static/description/images/customer _invoice-1.png new file mode 100644 index 000000000..a3991ce9b Binary files /dev/null and b/sale_discount_total/static/description/images/customer _invoice-1.png differ diff --git a/sale_discount_total/static/description/images/cybrosys.png b/sale_discount_total/static/description/images/cybrosys.png new file mode 100644 index 000000000..d76b5bafb Binary files /dev/null and b/sale_discount_total/static/description/images/cybrosys.png differ diff --git a/sale_discount_total/static/description/images/sale order.png b/sale_discount_total/static/description/images/sale order.png new file mode 100644 index 000000000..24f1fcbd0 Binary files /dev/null and b/sale_discount_total/static/description/images/sale order.png differ diff --git a/sale_discount_total/static/description/images/settings.png b/sale_discount_total/static/description/images/settings.png new file mode 100644 index 000000000..fabce434f Binary files /dev/null and b/sale_discount_total/static/description/images/settings.png differ diff --git a/sale_discount_total/static/description/index.html b/sale_discount_total/static/description/index.html new file mode 100644 index 000000000..d3ddd0cf5 --- /dev/null +++ b/sale_discount_total/static/description/index.html @@ -0,0 +1,302 @@ +
cybrosys-logo
+
+
+
+

Global Discount In Sale

+

Global Discount In Sale

+
+

Key Highlights

+
    +
  • Select 'Percentage' from Discount type and give discount percentage as Discount rate.
  • +
  • Select 'Amount' from Discount type and give discount amount as Discount rate.
  • +
  • System will update the value of Discount and Total
  • +
+
+
+
+
+
+
+
+ +
+
+ +

Overview

+
+

+ This module allows you to mention discount on Total of sale order and Total of Customer Invoice as percentage or as amount. +

+
+ +

Global Discount In Sale

+
+
    +
  • + Select 'Percentage' from Discount type and give discount percentage as Discount rate. +
  • +
  • + Select 'Amount' from Discount type and give discount amount as Discount rate. +
  • + +
  • + System will update the value of Discount and Total +
  • +
+
+ +
+
+

Screenshots

+
+
+
+ +
+
+
+
+ + +
+
    +
+
+
+
+
+
+
+

Suggested Products

+
+ +
+
+

Our Service

+
+ +
+
+
+

Our Industries

+
+ +
+
+
+ +
+
+

Trading

+

Easily procure and sell your products.

+
+
+
+
+ +
+
+

Manufacturing

+

Plan, track and schedule your operations.

+
+
+
+
+ +
+
+

Restaurant

+

Run your bar or restaurant methodical.

+
+
+
+
+ +
+
+

POS

+

Easy configuring and convivial selling.

+
+
+
+
+ +
+
+

E-commerce & Website

+

Mobile friendly, awe-inspiring product pages.

+
+
+
+
+ +
+
+

Hotel Management

+

An all-inclusive hotel management application.

+
+
+
+
+ +
+
+

Education

+

A Collaborative platform for educational management.

+
+
+
+
+ +
+
+

Service Management

+

Keep track of services and invoice accordingly.

+
+
+
+
+
+ +
+
+
+

Need Any Help?

+
+

If you have anything to share with us based on your use of this module, please let us know. We are ready to offer our support.

+
+

Email us

+

odoo@cybrosys.com / info@cybrosys.com

+
+
+

Contact Us

+ www.cybrosys.com +
+
+
+
+
+
+
+
+
+ +
+ + + + + + + +
+
+
+ \ No newline at end of file diff --git a/sale_discount_total/views/account_invoice_view.xml b/sale_discount_total/views/account_invoice_view.xml new file mode 100644 index 000000000..4a5af2d16 --- /dev/null +++ b/sale_discount_total/views/account_invoice_view.xml @@ -0,0 +1,41 @@ + + + + + + discount.account.invoice + account.move + + + + [16, 2] + + + + + +
+
+
+
+
+
+
+ + + + + + + + + + + + +
+
diff --git a/sale_discount_total/views/invoice_report.xml b/sale_discount_total/views/invoice_report.xml new file mode 100644 index 000000000..0f68f0c18 --- /dev/null +++ b/sale_discount_total/views/invoice_report.xml @@ -0,0 +1,20 @@ + + + + + + + + diff --git a/sale_discount_total/views/res_config_view.xml b/sale_discount_total/views/res_config_view.xml new file mode 100644 index 000000000..c9f7d5fc8 --- /dev/null +++ b/sale_discount_total/views/res_config_view.xml @@ -0,0 +1,33 @@ + + + + res.config.settings.view.form.inherit.sale.discount + res.config.settings + + + + + +
+
+ +
+
+
+
+ +
+
+
+
diff --git a/sale_discount_total/views/sale_order_report.xml b/sale_discount_total/views/sale_order_report.xml new file mode 100644 index 000000000..2b3e3f526 --- /dev/null +++ b/sale_discount_total/views/sale_order_report.xml @@ -0,0 +1,21 @@ + + + + + + + + \ No newline at end of file diff --git a/sale_discount_total/views/sale_view.xml b/sale_discount_total/views/sale_view.xml new file mode 100644 index 000000000..5c088d94b --- /dev/null +++ b/sale_discount_total/views/sale_view.xml @@ -0,0 +1,46 @@ + + + + + + discount.sale.order.form + sale.order + + + +