diff --git a/base_hospital_management/README.rst b/base_hospital_management/README.rst
new file mode 100755
index 000000000..b9b0a8c50
--- /dev/null
+++ b/base_hospital_management/README.rst
@@ -0,0 +1,46 @@
+.. image:: https://img.shields.io/badge/license-AGPL--3-blue.svg
+ :target: https://www.gnu.org/licenses/agpl-3.0-standalone.html
+ :alt: License: AGPL-3
+
+Hospital Management Odoo 16
+===========================
+This Module helps to manage day to day activities of a hospital.
+
+Configuration
+=============
+Install python-barcode (pip install python-barcode)
+
+License
+-------
+Affero General Public License, Version 3 (AGPL v3).
+(https://www.gnu.org/licenses/lgpl-3.0-standalone.html)
+
+Company
+-------
+* `Cybrosys Techno Solutions `__
+
+Credits
+-------
+* Developer:(V16) Ahammed Harshad P, Nihala MK, Gee Paul Joby, Mohamed Savad V, Athira P S, Unnimaya C O, Contact: odoo@cybrosys.com
+
+Contacts
+--------
+* Mail Contact : odoo@cybrosys.com
+* Website : https://cybrosys.com
+
+Bug Tracker
+-----------
+Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported.
+
+Maintainer
+==========
+.. image:: https://cybrosys.com/images/logo.png
+ :target: https://cybrosys.com
+
+This module is maintained by Cybrosys Technologies.
+
+For support and more information, please visit `Our Website `__
+
+Further information
+===================
+HTML Description: ``__
diff --git a/base_hospital_management/__init__.py b/base_hospital_management/__init__.py
new file mode 100755
index 000000000..dfd4453a7
--- /dev/null
+++ b/base_hospital_management/__init__.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 controllers
+from . import models
diff --git a/base_hospital_management/__manifest__.py b/base_hospital_management/__manifest__.py
new file mode 100755
index 000000000..9c98fa36e
--- /dev/null
+++ b/base_hospital_management/__manifest__.py
@@ -0,0 +1,112 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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": "Hospital Management Odoo 16",
+ "version": "16.0.1.0.0",
+ "category": "Industries",
+ "summary": """This Module Helps to Manage Patients Records, Doctors Details,
+ Lab Management , Employee Management etc.and there is Dashboard Created
+ under the module that help to Analyze Services like Patient Details,
+ Lab Details, Test Details Doctor's Allocations""",
+ "description": """The hospital management module can be used to handle
+ the day-to-day activities of the hospital. Managing patient scheduling,
+ making patient ID cards, creating patient lab test results, and adding
+ doctors, patients, prescriptions, vaccines, etc. are all made easier
+ with the help of this module. This app offers a different dashboards for
+ different users.""",
+ "author": "Cybrosys Techno Solutions",
+ "company": "Cybrosys Techno Solutions",
+ "maintainer": "Cybrosys Techno Solutions",
+ "website": "https://www.cybrosys.com",
+ "depends": ["website", "hr", "stock", "sale_management"],
+ "data": [
+ "security/base_hospital_management_groups.xml",
+ "security/doctor_allocation_security.xml",
+ "security/doctor_slot_security.xml",
+ "security/patient_lab_test_security.xml",
+ "security/ir.model.access.csv",
+ "data/ir_sequence_data.xml",
+ "data/ir_cron_data.xml",
+ "data/website_data.xml",
+ "views/menu_views.xml",
+ "views/inpatient_surgery_views.xml",
+ "views/hospital_bed_views.xml",
+ "views/blood_bank_views.xml",
+ "views/contra_indication_views.xml",
+ "views/booking_success_templates.xml",
+ "views/hospital_building_views.xml",
+ "views/hospital_degree_views.xml",
+ "views/doctor_allocation_views.xml",
+ "views/hr_employee_views.xml",
+ "views/hospital_inpatient_views.xml",
+ "views/hospital_insurance_views.xml",
+ "views/hospital_laboratory_views.xml",
+ "views/patient_lab_test_views.xml",
+ "views/lab_test_views.xml",
+ "views/lab_test_result_views.xml",
+ "views/medicine_brand_views.xml",
+ "views/menu_views.xml",
+ "views/hospital_outpatient_views.xml",
+ "views/res_partner_views.xml",
+ "views/patient_portal_templates.xml",
+ "views/hospital_vaccination_views.xml",
+ "views/product_template_views.xml",
+ "views/room_facility_views.xml",
+ "views/patient_card_templates.xml",
+ "views/booking_success_templates.xml",
+ "views/doctor_specialization_views.xml",
+ "views/hospital_pharmacy_views.xml",
+ "views/hospital_ward_views.xml",
+ "views/patient_booking_templates.xml",
+ "views/patient_room_views.xml",
+ "report/res_partner_reports.xml",
+ "report/lab_test_line_reports.xml",
+ "views/lab_test_line_views.xml",
+ ],
+ "demo": ["demo/hr_job_demo.xml"],
+ "assets": {
+ "web.assets_frontend": [
+ "base_hospital_management/static/src/js/prescription.js",
+ "base_hospital_management/static/src/js/website_page.js",
+ ],
+ "web.assets_backend": [
+ "base_hospital_management/static/src/xml/lab_dashboard_templates.xml",
+ "base_hospital_management/static/src/xml/doctor_dashboard_templates.xml",
+ "base_hospital_management/static/src/js/lab_dashboard.js",
+ "base_hospital_management/static/src/js/doctor_dashboard.js",
+ "base_hospital_management/static/src/css/lab_dashboard.css",
+ "base_hospital_management/static/src/xml/pharmacy_dashboard_templates.xml",
+ "base_hospital_management/static/src/js/pharmacy_dashboard.js",
+ "base_hospital_management/static/src/css/pharmacy_dashboard.css",
+ "base_hospital_management/static/src/xml/reception_dashboard_templates.xml",
+ "base_hospital_management/static/src/js/reception_dashboard.js",
+ "base_hospital_management/static/src/css/reception_dashboard.css",
+ "base_hospital_management/static/src/css/doctor_dashboard.css",
+ ],
+ },
+ "external_dependencies": {"python": ["python-barcode"]},
+ "images": ["static/description/banner.jpg"],
+ "license": "AGPL-3",
+ "installable": True,
+ "auto_install": False,
+ "application": True,
+}
diff --git a/base_hospital_management/controllers/__init__.py b/base_hospital_management/controllers/__init__.py
new file mode 100755
index 000000000..a57f9e4b7
--- /dev/null
+++ b/base_hospital_management/controllers/__init__.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 patient_booking
+from . import portal
+from . import view_portal
diff --git a/base_hospital_management/controllers/patient_booking.py b/base_hospital_management/controllers/patient_booking.py
new file mode 100755
index 000000000..2f0456497
--- /dev/null
+++ b/base_hospital_management/controllers/patient_booking.py
@@ -0,0 +1,78 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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, http
+from odoo.http import request
+
+
+class PatientBooking(http.Controller):
+ """Class for patient booking"""
+
+ @http.route('/patient_booking', type='http', auth="public", website=True)
+ def patient_booking(self):
+ """Function for patient booking from website."""
+ if request.env.user._is_public():
+ return request.redirect('/web/login')
+ values = {
+ 'user': request.env.user.name,
+ 'date': fields.date.today()
+ }
+ return request.render(
+ "base_hospital_management.patient_booking_form", values)
+
+ @http.route('/patient_booking/success', type='http',
+ website=True, csrf=False)
+ def patient_booking_submit(self, **kw):
+ """Function for submitting the patient booking"""
+ if request.env.user.partner_id.patient_seq in ['New', 'User',
+ 'Employee']:
+ request.env.user.partner_id.sudo().write(
+ {'patient_seq': request.env['ir.sequence'].sudo().next_by_code(
+ 'patient.sequence')}) or 'New'
+ op = request.env['hospital.outpatient'].sudo().create({
+ 'patient_id': request.env.user.partner_id.id,
+ 'doctor_id': int(kw.get("doctor-name")),
+ 'op_date': kw.get("date"),
+ 'reason': kw.get("reason")
+ })
+ op.sudo().action_confirm()
+ return request.redirect('/my/home')
+
+ @http.route('/patient_booking/get_doctors', type='json', auth="public",
+ website=True)
+ def update_doctors(self, **kw):
+ """Method for fetching doctor allocation for the selected date"""
+ domain = [('date', '=', kw.get('selected_date'))]
+ departments = []
+ doctors = []
+ if kw.get('department'):
+ domain.append(
+ ('doctor_id.department_id.id', '=', kw.get('department')))
+ allocation = request.env['doctor.allocation'].sudo().search(domain)
+ for rec in allocation:
+ if request.env.user.partner_id not in rec.mapped(
+ 'op_ids.patient_id'):
+ doctors.append({'id': rec.id, 'name': rec.name})
+ if ({'id': rec.department_id.id, 'name': rec.department_id.name}
+ not in departments):
+ departments.append({'id': rec.department_id.id,
+ 'name': rec.department_id.name})
+ return {'doctors': doctors, 'departments': departments}
diff --git a/base_hospital_management/controllers/portal.py b/base_hospital_management/controllers/portal.py
new file mode 100755
index 000000000..72d922bc7
--- /dev/null
+++ b/base_hospital_management/controllers/portal.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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.http import request
+from odoo.addons.portal.controllers.portal import CustomerPortal
+
+
+class WebsiteCustomerPortal(CustomerPortal):
+ """Class for inheriting _prepare_home_portal_values function """
+
+ def _prepare_home_portal_values(self, counters):
+ """Function for updating the counts of vaccinations, lab tests and op
+ of portal user"""
+ values = super()._prepare_home_portal_values(counters)
+ if 'vaccination_count' in counters:
+ values['vaccination_count'] = request.env[
+ 'hospital.vaccination'].sudo(). \
+ search_count([('patient_id.user_ids', '=', request.uid)])
+ if 'lab_test_count' in counters:
+ values['lab_test_count'] = request.env['patient.lab.test'].sudo(). \
+ search_count([('patient_id.user_ids', '=', request.uid)])
+ if 'op_count' in counters:
+ values['op_count'] = request.env[
+ 'hospital.outpatient'].sudo().search_count(
+ [('patient_id.user_ids', '=', request.uid)])
+ return values
diff --git a/base_hospital_management/controllers/view_portal.py b/base_hospital_management/controllers/view_portal.py
new file mode 100755
index 000000000..2ffe5f76b
--- /dev/null
+++ b/base_hospital_management/controllers/view_portal.py
@@ -0,0 +1,130 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 http
+from odoo.http import request
+
+
+class ViewPortal(http.Controller):
+ """Class holding portal view methods"""
+
+ @http.route('/my/vaccinations', type='http', auth="public",
+ website=True)
+ def portal_my_vaccine(self, **kw):
+ """Function for rendering vaccination details of portal user"""
+ v_list = []
+ for rec in request.env['hospital.vaccination'].sudo().search(
+ [('patient_id.user_ids.id', '=', request.uid)]):
+ request.env.cr.execute(
+ f"""SELECT id FROM ir_attachment WHERE res_id = {rec.id}
+ and res_model='hospital.vaccination' """)
+ attachment_id = False
+ attachment = request.env.cr.dictfetchall()
+ if attachment:
+ attachment_id = attachment[0]['id']
+ data = {
+ 'id': rec.id,
+ 'name': rec.name,
+ 'vaccine_date': rec.vaccine_date,
+ 'dose': rec.dose,
+ 'vaccine_product_id': rec.vaccine_product_id.name,
+ 'vaccine_price': rec.vaccine_price,
+ 'attachment_id': attachment_id
+ }
+ v_list.append(data)
+ values = {
+ 'vaccinations': v_list,
+ 'page_name': 'vaccination'
+ }
+ return request.render("base_hospital_management.portal_my_vaccines",
+ values)
+
+ @http.route(['/my/tests'], type='http', auth="public", website=True)
+ def portal_my_tests(self, **kw):
+ """Function for rendering tests of portal user"""
+ tests_list = []
+ for rec in request.env['patient.lab.test'].sudo().search(
+ [('patient_id.user_ids', '=', request.uid)]):
+ request.env['account.move'].sudo().search(
+ [('ref', '=', rec.test_id.name)
+ ], limit=1)
+ data = {
+ 'id': rec.id,
+ 'name': rec.test_id.name,
+ 'date': rec.date
+ }
+ tests_list.append(data)
+ values = {
+ 'tests': tests_list,
+ 'page_name': 'lab_test'
+ }
+ return request.render("base_hospital_management.portal_my_tests",
+ values)
+
+ @http.route('/my/tests/', type="http", auth="public",
+ website=True)
+ def tests_view(self, test_id):
+ """Function for rendering test results of portal user"""
+ result_list = []
+ all_test = request.env['patient.lab.test'].sudo().browse(test_id)
+ test_result_ids = request.env['lab.test.result'].sudo().search(
+ [('id', 'in', all_test.result_ids.ids)])
+ for rec in test_result_ids:
+ query = f"""SELECT id FROM ir_attachment WHERE res_id = {rec.id}
+ and res_model='lab.test.result' """
+ request.env.cr.execute(query)
+ attachment_id = False
+ attachment = request.env.cr.dictfetchall()
+ if attachment:
+ attachment_id = attachment[0]['id']
+ result_list.append({
+ 'id': rec.id,
+ 'name': rec.test_id.name,
+ 'result': rec.result,
+ 'price': rec.price,
+ 'attachment_id': attachment_id,
+ })
+ values = {
+ 'all_test_id': all_test.id,
+ 'results': result_list,
+ 'page_name': 'test_results'
+ }
+ return request.render(
+ "base_hospital_management.portal_my_tests_results", values)
+
+ @http.route('/my/op', type='http', auth="public",
+ website=True)
+ def portal_my_op(self, **kw):
+ """Function for rendering prescriptions of portal user"""
+ op = request.env['hospital.outpatient'].sudo().search_read(
+ [('patient_id.user_ids.id', '=', request.uid)],
+ ['op_reference', 'op_date', 'doctor_id', 'slot',
+ 'prescription_ids'])
+ for record in op:
+ hours = int(record['slot'])
+ minutes = int((record['slot'] - hours) * 60)
+ record['slot'] = '{:02d}:{:02d}'.format(hours, minutes)
+ values = {
+ 'op': op,
+ 'page_name': 'op'
+ }
+ return request.render(
+ "base_hospital_management.portal_my_op", values)
diff --git a/base_hospital_management/data/ir_cron_data.xml b/base_hospital_management/data/ir_cron_data.xml
new file mode 100755
index 000000000..a2db6fdf7
--- /dev/null
+++ b/base_hospital_management/data/ir_cron_data.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+ Blood Bank Availability
+
+ code
+ model.action_change_availability()
+ 3
+ months
+ -1
+
+
+
diff --git a/base_hospital_management/data/ir_sequence_data.xml b/base_hospital_management/data/ir_sequence_data.xml
new file mode 100755
index 000000000..17d42dded
--- /dev/null
+++ b/base_hospital_management/data/ir_sequence_data.xml
@@ -0,0 +1,74 @@
+
+
+
+
+
+ Blood Bank Sequence
+ blood.bank
+ BB/
+ 3
+ 1
+ 1
+
+
+
+ Building Sequence
+ building.sequence
+ BC/
+ 3
+ 1
+ 1
+
+
+
+ Inpatient sequence
+ hospital.inpatient
+ IN/PAT
+ 3
+ 1
+ 1
+
+
+
+ Lab Test Sequence
+ lab.test.sequence
+ LB/TS/
+ 3
+ 1
+ 1
+
+
+
+ Lab Test Draft Sequence
+ lab_tests.draft.sequence
+ LB/DR/
+ 3
+ 1
+ 1
+
+
+
+ Laboratory Sequence
+ laboratory.sequence
+ LAB
+ 3
+
+
+
+ Patient sequence
+ patient.sequence
+ PAT
+ 3
+ 1
+ 1
+
+
+
+ Vaccination Sequence
+ vaccination.sequence
+ VAC
+ 3
+
+
+
diff --git a/base_hospital_management/data/website_data.xml b/base_hospital_management/data/website_data.xml
new file mode 100755
index 000000000..43a75acdb
--- /dev/null
+++ b/base_hospital_management/data/website_data.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+ Booking
+ /patient_booking
+
+ 50
+
+
+
diff --git a/base_hospital_management/demo/hr_job_demo.xml b/base_hospital_management/demo/hr_job_demo.xml
new file mode 100755
index 000000000..f96e7005e
--- /dev/null
+++ b/base_hospital_management/demo/hr_job_demo.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+ Doctor
+
+
+ Nurse
+
+
+ Receptionist
+
+
+ Pharmacist
+
+
+ Staff
+
+
+ Lab Technician
+
+
+
diff --git a/base_hospital_management/doc/RELEASE_NOTES.md b/base_hospital_management/doc/RELEASE_NOTES.md
new file mode 100755
index 000000000..6948336ea
--- /dev/null
+++ b/base_hospital_management/doc/RELEASE_NOTES.md
@@ -0,0 +1,7 @@
+## Module
+
+#### 27.12.2023
+#### Version 16.0.1.0.0
+#### ADD
+
+- Initial commit for Hospital Management Odoo 16
diff --git a/base_hospital_management/models/__init__.py b/base_hospital_management/models/__init__.py
new file mode 100755
index 000000000..f02d44d8d
--- /dev/null
+++ b/base_hospital_management/models/__init__.py
@@ -0,0 +1,58 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 account_payment_register
+from . import blood_bank
+from . import contra_indication
+from . import blood_donation
+from . import doctor_allocation
+from . import doctor_round
+from . import doctor_slot
+from . import doctor_specialization
+from . import hospital_bed
+from . import hospital_building
+from . import hospital_degree
+from . import hospital_family
+from . import hospital_inpatient
+from . import hospital_insurance
+from . import hospital_laboratory
+from . import hospital_outpatient
+from . import hospital_pharmacy
+from . import hospital_vaccination
+from . import hospital_ward
+from . import hr_employee
+from . import inpatient_payment
+from . import inpatient_surgery
+from . import ir_attachment
+from . import lab_medicine_line
+from . import lab_test
+from . import lab_test_line
+from . import lab_test_result
+from . import medicine_brand
+from . import nursing_plan
+from . import patient_lab_test
+from . import patient_room
+from . import pharmacy_medicine
+from . import prescription_line
+from . import product_template
+from . import res_partner
+from . import res_users
+from . import room_facility
diff --git a/base_hospital_management/models/account_payment_register.py b/base_hospital_management/models/account_payment_register.py
new file mode 100755
index 000000000..79b745544
--- /dev/null
+++ b/base_hospital_management/models/account_payment_register.py
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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, models
+
+
+class AccountPaymentRegister(models.TransientModel):
+ """
+ Adding inpatient field to invoicing model.
+ """
+ _inherit = "account.payment.register"
+
+ @api.model
+ def create(self, vals_list):
+ """Create records to inpatient payment"""
+ self.env['inpatient.payment'].sudo().create({
+ 'name': vals_list['communication'],
+ 'subtotal': vals_list['amount'],
+ 'inpatient_id': self.env['hospital.inpatient'].sudo().search([(
+ 'patient_id', '=', vals_list['partner_id'])],
+ order='create_date desc', limit=1).id,
+ 'date': vals_list['payment_date']
+ })
+ return super().create(vals_list)
diff --git a/base_hospital_management/models/blood_bank.py b/base_hospital_management/models/blood_bank.py
new file mode 100755
index 000000000..9b721d40e
--- /dev/null
+++ b/base_hospital_management/models/blood_bank.py
@@ -0,0 +1,102 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 BloodBank(models.Model):
+ """Class holding Blood bank details"""
+ _name = 'blood.bank'
+ _description = "Blood Bank"
+
+ partner_id = fields.Many2one('res.partner',
+ string='Donor Name',
+ domain=[('patient_seq', 'not in',
+ ['New', 'Employee', 'User'])],
+ help='Name of the blood donor',
+ required=True)
+ name = fields.Char(string='Sequence',
+ help='Sequence number indicating the blood bank',
+ index=True,
+ default=lambda self: 'New')
+ date = fields.Date(string='Date', help='Blood donating date',
+ default=fields.date.today())
+ blood_type = fields.Selection([('a_positive', 'A+'),
+ ('a_negative', 'A-'),
+ ('b_positive', 'B+'), ('b_negative', 'B-'),
+ ('o_positive', 'O+'), ('o_negative', '0-'),
+ ('ab_positive', 'AB+'),
+ ('ab_negative', 'AB-')],
+ string='Blood Group',
+ help='Choose your blood group', required=True,
+ group_expand='_group_expand_states')
+ blood_donation_ids = fields.One2many('blood.donation',
+ 'blood_bank_id',
+ string='Contra Indications',
+ help='Lists all the '
+ 'contraindications')
+ state = fields.Selection([('avail', 'Available'),
+ ('not', 'Unavailable')],
+ string='State', help='State of the blood donation',
+ readonly=True, default="avail")
+ assigned_patient_id = fields.Many2one('res.partner',
+ string='Receiver',
+ domain=[('patient_seq', 'not in',
+ ['New', 'Employee',
+ 'User'])],
+ help='Choose the patient to whom '
+ 'blood is donating')
+
+ @api.model
+ def create(self, vals):
+ """Function for creating blood sequence number"""
+ if vals.get('name', 'New') == 'New':
+ vals['name'] = self.env['ir.sequence'].next_by_code(
+ 'blood.bank') or 'New'
+ return super().create(vals)
+
+ @api.onchange('partner_id')
+ def _onchange_partner_id(self):
+ """Function for listing all contra indications"""
+ self.blood_donation_ids = False
+ self.sudo().write({
+ 'blood_donation_ids': [(0, 0, {
+ 'questions': rec.blood_donation_question})
+ for rec in
+ self.env['contra.indication'].sudo().search(
+ [])]})
+
+ def _group_expand_states(self, states, domain, order):
+ """Method for expanding all blood groups in kanban view"""
+ return [key for
+ key, val in type(self).blood_type.selection]
+
+ def action_blood_available(self):
+ """Change the state to unavailable"""
+ self.sudo().write({
+ 'state': 'not'
+ })
+
+ def action_change_availability(self):
+ """Cron action for changing the state of the record"""
+ for rec in self.sudo().search([]):
+ if rec.date <= fields.Date.subtract(fields.Date.today(), months=1):
+ rec.state = 'avail'
diff --git a/base_hospital_management/models/blood_donation.py b/base_hospital_management/models/blood_donation.py
new file mode 100755
index 000000000..4c1f82c59
--- /dev/null
+++ b/base_hospital_management/models/blood_donation.py
@@ -0,0 +1,38 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 BloodDonation(models.Model):
+ """Class holding blood donation details"""
+ _name = 'blood.donation'
+ _description = 'Blood Donation'
+ _rec_name = 'questions'
+
+ questions = fields.Text(string='Contra Indications',
+ help='Contraindications of the blood donor')
+ is_true = fields.Boolean(string='Is True',
+ help='True for contraindications')
+ blood_bank_id = fields.Many2one('blood.bank',
+ string='Blood Bank',
+ help='Blood bank corresponding to the '
+ 'donor')
diff --git a/base_hospital_management/models/contra_indication.py b/base_hospital_management/models/contra_indication.py
new file mode 100755
index 000000000..c36a66470
--- /dev/null
+++ b/base_hospital_management/models/contra_indication.py
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 ContraIndication(models.Model):
+ """Class holding the contra indications"""
+ _name = 'contra.indication'
+ _description = 'Contra Indication'
+ _rec_name = 'blood_donation_question'
+
+ blood_donation_question = fields.Text(string='Contra Indications',
+ help='Contra indications of the '
+ 'blood donor')
diff --git a/base_hospital_management/models/doctor_allocation.py b/base_hospital_management/models/doctor_allocation.py
new file mode 100755
index 000000000..38a3b859e
--- /dev/null
+++ b/base_hospital_management/models/doctor_allocation.py
@@ -0,0 +1,220 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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
+from odoo.exceptions import ValidationError
+
+
+class DoctorAllocation(models.Model):
+ """Class holding doctor allocations"""
+ _name = 'doctor.allocation'
+ _description = 'Doctor Allocation'
+
+ doctor_id = fields.Many2one('hr.employee', string="Doctor",
+ help='Name of the doctor',
+ domain=[('job_id.name', '=', 'Doctor')])
+ name = fields.Char(string="Name", readonly=True, default='New',
+ help='Name of the allocation')
+ department_id = fields.Many2one(string='Department',
+ help='Department of the doctor',
+ related='doctor_id.department_id')
+ op_ids = fields.One2many('hospital.outpatient',
+ 'doctor_id',
+ string='Booking',
+ help='Patient booking belongs to this '
+ 'allocation')
+ company_id = fields.Many2one('res.company', string='Company',
+ default=lambda self: self.env.company.id,
+ help='Indicates the company')
+ is_doctor = fields.Boolean(string='Is Doctor', help='True for doctors.')
+ date = fields.Date(string='Date',
+ help='Indicate the allocated date for a doctor',
+ default=fields.Date.today())
+ work_to = fields.Float(string='Work To', required=True,
+ help='Allocation time ending time in 24 hrs format')
+ work_from = fields.Float(string='Work From', required=True,
+ help='Allocation time starting time in 24 hrs '
+ 'format')
+ time_avg = fields.Float(string='Duration', help="Average Consultation time "
+ "per Patient in minutes",
+ readonly=False,
+ related='doctor_id.time_avg')
+ patient_type = fields.Selection([('inpatient', 'Inpatient'),
+ ('outpatient', 'Outpatient')],
+ string='Patient Type',
+ help='Indicates the type of patient')
+ patient_limit = fields.Integer(string='Limit Patient',
+ help='Maximum number of patients allowed '
+ 'per allocation', store=True,
+ compute='_compute_patient_limit', )
+ patient_count = fields.Integer(string='Patient Count',
+ help='Number of patient under '
+ 'this allocation',
+ compute='_compute_patient_count')
+ slot_remaining = fields.Integer(string='Slots Remaining',
+ help='Number of slots remaining in this'
+ ' allocation', store=True,
+ compute='_compute_slot_remaining')
+ latest_slot = fields.Float(string='Available Slot',
+ help='Indicates the latest available slot')
+ state = fields.Selection(
+ [('draft', 'Draft'), ('confirm', 'Confirmed'),
+ ('cancel', 'Cancelled')],
+ default='draft', string='State', help='State of Doctor allocation')
+
+ @api.model
+ def create(self, vals):
+ """Method for creating name"""
+ work_from_hr = int(vals['work_from'])
+ work_from_min = int((vals['work_from'] - work_from_hr) * 60)
+ work_from = "{:02d}:{:02d}".format(work_from_hr, work_from_min)
+ work_to_hr = int(vals['work_to'])
+ work_to_min = int((vals['work_to'] - work_to_hr) * 60)
+ work_to = "{:02d}:{:02d}".format(work_to_hr, work_to_min)
+ doctor_group = self.env.ref(
+ 'base_hospital_management.base_hospital_management_group_doctor')
+ if doctor_group in self.env.user.groups_id:
+ default_doctor_id = self.env['hr.employee'].sudo().search(
+ [('user_id', '=', self.env.user.id)], limit=1)
+ if default_doctor_id:
+ vals[
+ 'name'] = (default_doctor_id.name + ': ' + work_from + '-'
+ + work_to)
+ else:
+ vals['name'] = self.env['hr.employee'].sudo().browse(
+ vals['doctor_id']).name + ': ' + work_from + '-' + work_to
+ return super().create(vals)
+
+ @api.onchange('work_from', 'work_to')
+ def _onchange_work_from(self):
+ """Method for calculating name"""
+ if self.work_from and self.work_to:
+ work_from_hr = int(self.work_from)
+ work_from_min = int((self.work_from - work_from_hr) * 60)
+ work_from = "{:02d}:{:02d}".format(work_from_hr, work_from_min)
+ work_to_hr = int(self.work_to)
+ work_to_min = int((self.work_to - work_to_hr) * 60)
+ work_to = "{:02d}:{:02d}".format(work_to_hr, work_to_min)
+ self.name = self.doctor_id.name + ': ' + work_from + '-' + work_to
+
+ @api.model
+ def default_get(self, doctor_id):
+ """Method for making doctor field readonly and applying default value
+ for doctor login"""
+ res = super().default_get(doctor_id)
+ doctor_group = self.env.ref(
+ 'base_hospital_management.base_hospital_management_group_doctor')
+ if doctor_group in self.env.user.groups_id:
+ default_doctor_id = self.env['hr.employee'].sudo().search(
+ [('user_id', '=', self.env.user.id)], limit=1)
+ if default_doctor_id:
+ res['doctor_id'] = default_doctor_id.id
+ res['is_doctor'] = True
+ self.is_doctor = True
+ else:
+ self.is_doctor = False
+ res['is_doctor'] = False
+ return res
+
+ @api.constrains('work_from', 'work_to', 'date')
+ def _check_overlap(self):
+ """Method for checking overlapping"""
+ for allocation in self:
+ if allocation.work_from >= allocation.work_to:
+ raise ValidationError("Work From must be less than Work To.")
+ overlapping_allocations = self.sudo().search([
+ ('id', '!=', allocation.id),
+ ('date', '=', allocation.date),
+ ('doctor_id', '=', allocation.doctor_id.id),
+ '|',
+ '&', ('work_from', '<=', allocation.work_from),
+ ('work_to', '>=', allocation.work_from),
+ '&', ('work_from', '<=', allocation.work_to),
+ ('work_to', '>=', allocation.work_to)
+ ])
+ if overlapping_allocations:
+ raise ValidationError(
+ "Overlap detected with another doctor allocation on the "
+ "same date.")
+
+ @api.depends('work_from', 'work_to', 'time_avg')
+ def _compute_patient_limit(self):
+ """Method for computing patient limit"""
+ for record in self:
+ if (record.work_from and record.work_to and record.time_avg
+ and record.time_avg > 0):
+ patient_slots = int(
+ (record.work_to - record.work_from) / record.time_avg)
+ if patient_slots <= 0:
+ raise ValidationError(
+ "Work From must be less than Work To.")
+ else:
+ record.patient_limit = patient_slots
+ else:
+ record.patient_limit = 0
+
+ @api.depends('op_ids')
+ def _compute_patient_count(self):
+ """Method for computing patient count"""
+ for rec in self:
+ rec.patient_count = len(rec.op_ids)
+
+ @api.depends('op_ids', 'patient_count', 'patient_limit')
+ def _compute_slot_remaining(self):
+ """Method for computing slot remaining"""
+ for rec in self:
+ rec.slot_remaining = rec.patient_limit - rec.patient_count
+
+ def action_get_patient_booking(self):
+ """Returns form view of bed"""
+ return {
+ 'name': "Patient Booking",
+ 'type': 'ir.actions.act_window',
+ 'view_mode': 'tree,form',
+ 'res_model': 'hospital.outpatient',
+ 'domain': [('id', 'in', self.op_ids.ids)],
+ 'context': {'create': False}
+ }
+
+ def action_confirm_allocation(self):
+ """Confirmation of allocation"""
+ self.state = 'confirm'
+
+ def action_cancel_allocation(self):
+ """Method for cancelling a allocation"""
+ self.state = 'cancel'
+
+ @api.model
+ def get_allocation_lines(self):
+ """Returns allocated hour details to display on the dashboard"""
+ data_list = []
+ allocated_hour = self.sudo().search([
+ ('doctor_id.user_id', '=', self.env.user.id)
+ ])
+ for rec in allocated_hour:
+ data_list.append({
+ 'date': rec.date,
+ 'name': rec.name,
+ 'patient_type': rec.patient_type,
+ 'patient_limit': rec.patient_limit,
+ 'patient_count': rec.patient_count
+ })
+ return {'record': data_list}
diff --git a/base_hospital_management/models/doctor_round.py b/base_hospital_management/models/doctor_round.py
new file mode 100755
index 000000000..1ef807159
--- /dev/null
+++ b/base_hospital_management/models/doctor_round.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 DoctorRound(models.Model):
+ """Class holding doctor round details"""
+ _name = 'doctor.round'
+ _description = "Doctor Rounds"
+
+ admission_id = fields.Many2one('hospital.inpatient',
+ string='Patient',
+ help='Choose the patient')
+ doctor_id = fields.Many2one('hr.employee',
+ domain=[('job_id.name', '=', 'Doctor')],
+ string='Doctor', help='Choose your doctor')
+ date = fields.Datetime(string='Visit Time', help='Choose the visit time '
+ 'of doctor')
+ status = fields.Char(string='Status', help='Status of doctor rounds')
+ notes = fields.Text(string='Note', help='Notes regarding the rounds')
diff --git a/base_hospital_management/models/doctor_slot.py b/base_hospital_management/models/doctor_slot.py
new file mode 100755
index 000000000..a576d5e25
--- /dev/null
+++ b/base_hospital_management/models/doctor_slot.py
@@ -0,0 +1,136 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 DoctorSlot(models.Model):
+ """Model for handling a doctor's slot for surgery"""
+ _name = 'doctor.slot'
+ _description = "Doctor Slot"
+ _inherit = ["mail.thread", "mail.activity.mixin"]
+
+ doctor_id = fields.Many2one('hr.employee', string="Doctor",
+ help='Doctors name',
+ domain=[('job_id.name', '=', 'Doctor')])
+ date_start = fields.Datetime(default=fields.date.today(), string='Date',
+ help='Date of surgery')
+ patient_id = fields.Many2one('res.partner',
+ domain=[('patient_seq', 'not in',
+ ['New', 'Employee', 'User'])],
+ string='Patient', help='Name of the patient')
+ name = fields.Char(string='Surgery', help='Name of surgery')
+ state = fields.Selection([('confirmed', 'Confirmed'),
+ ('cancel', 'Cancel'),
+ ('done', 'Done'),
+ ('draft', 'Draft')], default='draft',
+ string='State', help='State of the slot')
+ time = fields.Float(string='Time', help='Time of surgery')
+ hours_to_take = fields.Float(string='Duration',
+ help='Time duration for the surgery')
+ company_id = fields.Many2one('res.company', string='Company',
+ default=lambda self: self.env.company.id)
+
+ def hospital_inpatient_confirm(self):
+ """Inpatient confirmation from Doctor's dashboard"""
+ data_list = []
+ for rec in self.env['doctor.slot'].sudo().search(
+ [('doctor_id.user_id', '=', self.env.user.id),
+ ('state', '=', 'confirmed')]):
+ data_list.append({
+ 'id': rec.id,
+ 'planned_date': rec.date_start,
+ 'patient_id': rec.patient_id.name,
+ 'name': rec.name,
+ 'state': rec.state
+ })
+ return {
+ 'record': data_list
+ }
+
+ def hospital_inpatient_cancel(self):
+ """Inpatients cancellation from Doctor's dashboard"""
+ data_list = []
+ for rec in self.env['doctor.slot'].sudo().search(
+ [('doctor_id.user_id', '=', self.env.user.id),
+ ('state', '=', 'cancel')]):
+ data_list.append({
+ 'id': rec.id,
+ 'planned_date': rec.date_start,
+ 'patient_id': rec.patient_id.name,
+ 'name': rec.name,
+ 'state': rec.state
+ })
+ return {
+ 'record': data_list
+ }
+
+ def hospital_inpatient_done(self):
+ """Inpatient done function from doctor's dashboard"""
+ data_list = []
+ for rec in self.env['doctor.slot'].sudo().search(
+ [('doctor_id.user_id', '=', self.env.user.id),
+ ('state', '=', 'done')]):
+ data_list.append({
+ 'id': rec.id,
+ 'planned_date': rec.date_start,
+ 'patient_id': rec.patient_id.name,
+ 'name': rec.name,
+ 'state': rec.state
+ })
+ return {
+ 'record': data_list
+ }
+
+ def action_get_doctor_slot(self):
+ """Function for returning doctor's slot to doctor's dashboard"""
+ data_list = []
+ for rec in self.sudo().search(
+ [('doctor_id.user_id', '=', self.env.user.id),
+ ('state', '=', 'draft')]):
+ data_list.append({
+ 'id': rec.id,
+ 'planned_date': rec.date_start,
+ 'patient_id': rec.patient_id.patient_seq,
+ 'name': rec.name,
+ 'state': rec.state
+ })
+ return {
+ 'record': data_list
+ }
+
+ def action_confirm(self):
+ """Function for confirming a slot"""
+ self.sudo().write({
+ 'state': 'confirmed'
+ })
+
+ def action_cancel(self):
+ """Function for cancelling a slot"""
+ self.sudo().write({
+ 'state': 'cancel'
+ })
+
+ def action_done(self):
+ """Function for change the state to done"""
+ self.sudo().write({
+ 'state': 'done'
+ })
diff --git a/base_hospital_management/models/doctor_specialization.py b/base_hospital_management/models/doctor_specialization.py
new file mode 100755
index 000000000..10574efec
--- /dev/null
+++ b/base_hospital_management/models/doctor_specialization.py
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 DoctorSpecialization(models.Model):
+ """Class holding doctor's specializations"""
+ _name = 'doctor.specialization'
+ _description = 'Doctor Specialization'
+ _rec_name = 'specialization'
+
+ specialization = fields.Char(string="Specialization",
+ help='Specify the name of specialization')
diff --git a/base_hospital_management/models/hospital_bed.py b/base_hospital_management/models/hospital_bed.py
new file mode 100755
index 000000000..4c34d0964
--- /dev/null
+++ b/base_hospital_management/models/hospital_bed.py
@@ -0,0 +1,59 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 HospitalBed(models.Model):
+ """Class holding hospital bed details"""
+ _name = 'hospital.bed'
+ _description = 'Beds'
+
+ _sql_constraints = [('unique_room', 'unique (name)',
+ 'Bed number should be unique!')]
+ name = fields.Char(string="Bed Number", help='Indicates the unique '
+ 'number for a bed',
+ required="True")
+ bed_type = fields.Selection([('gatch', 'Gatch Bed'),
+ ('electric', 'Electric'),
+ ('stretcher', 'Stretcher'),
+ ('low', 'Low Bed'),
+ ('air', 'Low Air Loss'),
+ ('circo', 'Circo Electric'),
+ ('clinitron', 'Clinitron'),
+ ], string="Type", help='Type of bed')
+ note = fields.Text(string="Notes", help='Notes regarding bed')
+ ward_id = fields.Many2one('hospital.ward', string="Ward",
+ help='Indicates the ward to which the bed'
+ ' belongs to')
+ room_id = fields.Many2one('patient.room', string="Room",
+ help='Indicates the room to which the bed'
+ ' belongs to')
+ currency_id = fields.Many2one('res.currency', string='Currency',
+ help='Currency in which bed rent calculates',
+ default=lambda self:
+ self.env.user.company_id.currency_id.id,
+ required=True)
+ bed_rent = fields.Monetary(string='Rent', help="The charge for the bed")
+ state = fields.Selection([('avail', 'Available'), ('not', 'Unavailable')],
+ string='State', readonly=True,
+ help='State of the bed',
+ default="avail")
diff --git a/base_hospital_management/models/hospital_building.py b/base_hospital_management/models/hospital_building.py
new file mode 100755
index 000000000..14df8375d
--- /dev/null
+++ b/base_hospital_management/models/hospital_building.py
@@ -0,0 +1,87 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 HospitalBuilding(models.Model):
+ """Class containing field and functions related to hospital building"""
+ _name = 'hospital.building'
+ _description = 'Buildings'
+
+ notes = fields.Text(string='Notes', help='Notes regarding the building')
+ name = fields.Char(string='Block Code',
+ help='Code for uniquely identifying a block',
+ copy=False, readonly=True, index=True,
+ default=lambda self: 'New')
+ phone = fields.Char(string='Phone',
+ help='Phone number for contact the building')
+ mobile = fields.Char(string='Mobile',
+ help='Mobile number for contact the building')
+ email = fields.Char(string='Email', help='Email of the building')
+ room_count = fields.Integer(string="Rooms",
+ help='Number of rooms in the building',
+ compute="_compute_room_count")
+ ward_count = fields.Integer(string="Wards",
+ help='Number of wards in the building',
+ compute="_compute_ward_count")
+
+ @api.model
+ def create(self, vals):
+ """Create building sequence"""
+ if vals.get('name', 'New') == 'New':
+ vals['name'] = self.env['ir.sequence'].next_by_code(
+ 'building.sequence') or 'New'
+ return super().create(vals)
+
+ def _compute_room_count(self):
+ """Calculates room_count in a building"""
+ for rec in self:
+ rec.room_count = self.env['patient.room'].sudo().search_count([(
+ 'building_id', '=', rec.id)])
+
+ def _compute_ward_count(self):
+ """Counting wards in the building"""
+ for rec in self:
+ rec.ward_count = self.env['hospital.ward'].sudo().search_count([(
+ 'building_id', '=', rec.id)])
+
+ def get_room_count(self):
+ """Smart button action for viewing all rooms in a building"""
+ return {
+ 'name': 'Room',
+ 'domain': [('building_id', '=', self.id)],
+ 'type': 'ir.actions.act_window',
+ 'res_model': 'patient.room',
+ 'view_mode': 'tree,form',
+ 'context': {'create': False},
+ }
+
+ def get_ward_count(self):
+ """Smart button action for viewing all wards in a building"""
+ return {
+ 'name': 'Wards',
+ 'domain': [('building_id', '=', self.id)],
+ 'type': 'ir.actions.act_window',
+ 'res_model': 'hospital.ward',
+ 'view_mode': 'tree,form',
+ 'context': {'create': False},
+ }
diff --git a/base_hospital_management/models/hospital_degree.py b/base_hospital_management/models/hospital_degree.py
new file mode 100755
index 000000000..5448406c1
--- /dev/null
+++ b/base_hospital_management/models/hospital_degree.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 HospitalDegree(models.Model):
+ """Class holding degree details of Doctor"""
+ _name = 'hospital.degree'
+ _description = 'Degree'
+
+ name = fields.Char(string="Degree", help='Degree of the staff')
diff --git a/base_hospital_management/models/hospital_family.py b/base_hospital_management/models/hospital_family.py
new file mode 100755
index 000000000..0116c5ec5
--- /dev/null
+++ b/base_hospital_management/models/hospital_family.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 HospitalFamily(models.Model):
+ """Class holding hospital family details"""
+ _name = 'hospital.family'
+ _description = 'Hospital Family'
+
+ name = fields.Char(string="Name", help='Name of family member')
+ relation = fields.Char(string="Relation", help='Relation with the patient')
+ age = fields.Integer(string="Age", help='Age of family member')
+ deceased = fields.Selection([('yes', 'Yes'), ('no', 'NO')],
+ string="Diseased", help='Specify whether the '
+ 'family member is '
+ 'alive or not')
+ family_id = fields.Many2one('res.partner',
+ string="Family ID", help='Choose the family '
+ 'member')
diff --git a/base_hospital_management/models/hospital_inpatient.py b/base_hospital_management/models/hospital_inpatient.py
new file mode 100755
index 000000000..49383aab5
--- /dev/null
+++ b/base_hospital_management/models/hospital_inpatient.py
@@ -0,0 +1,482 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 api, fields, models
+
+
+class HospitalInpatient(models.Model):
+ """Class holding inpatient details"""
+ _name = 'hospital.inpatient'
+ _description = 'Inpatient'
+ _inherit = ['mail.thread.cc', 'mail.activity.mixin']
+
+ patient_id = fields.Many2one('res.partner', string="Patient",
+ domain=[('patient_seq', 'not in',
+ ['New', 'Employee', 'User'])],
+ required=True, help='Choose the patient')
+ name = fields.Char(string="Sequence Number", store=True,
+ copy=False, readonly=True, index=True,
+ help='Sequence number of inpatient for uniquely '
+ 'identifying',
+ default=lambda self: 'New')
+ reason = fields.Text(
+ string="Reason For Admission",
+ help="Current reason for hospitalization of the patient")
+ bed_id = fields.Many2one('hospital.bed', string='Bed',
+ help='Choose the bed')
+ room_id = fields.Many2one('patient.room', string='Room',
+ help='Choose the room to which patient admitted'
+ ' to')
+ building_id = fields.Many2one(
+ 'hospital.building', related='room_id.building_id',
+ string="Block", help='Name of the block')
+ room_building_id = fields.Many2one(
+ 'hospital.building', related='room_id.building_id',
+ string="Room Building",
+ help='Name of the building to which room belongs to')
+ ward_id = fields.Many2one('hospital.ward',
+ related='bed_id.ward_id',
+ string='Ward',
+ help='Ward to which the bed belongs to')
+ type_admission = fields.Selection([('emergency',
+ 'Emergency Admission'),
+ ('routine', 'Routine Admission')],
+ string="Admission Type",
+ help='The type of admission',
+ required=True)
+ attending_doctor_id = fields.Many2one('hr.employee',
+ string="Attending Doctor",
+ required=True,
+ help='Name of attending doctor',
+ domain=[
+ ('job_id.name', '=', 'Doctor')])
+ operating_doctor_id = fields.Many2one('hr.employee',
+ string="Operating Doctor",
+ help='Name of operating doctor',
+ domain=[
+ ('job_id.name', '=', 'Doctor')])
+ hosp_date = fields.Date(string="Admission Date",
+ help='Date of hospitalisation',
+ default=fields.date.today())
+ discharge_date = fields.Date(string="Discharge Date",
+ help='Date of discharge', copy=False)
+ condition = fields.Text(
+ string="Condition Before Hospitalization",
+ help="The condition of the patient before he/she is admitted to"
+ " the hospital")
+ nursing_plan_ids = fields.One2many('nursing.plan',
+ 'admission_id',
+ string='Nursing Plan',
+ help='Nursing plan of the inpatient')
+ active = fields.Boolean(string='Active', default=True,
+ help='True for active inpatients')
+ doctor_round_ids = fields.One2many('doctor.round',
+ 'admission_id',
+ string='Doctor Rounds',
+ help='Doctor rounds of the patient')
+ discharge_plan = fields.Text(string="Discharge Plan",
+ help='Discharge plan of the inpatient')
+ notes = fields.Text(string="Notes", help='Notes regarding the inpatient')
+ bed_rent = fields.Monetary(string='Rent Per Day', related='bed_id.bed_rent',
+ help='Rent for the bed')
+ currency_id = fields.Many2one('res.currency', string='Currency',
+ help='Currency in which rent is calculating',
+ default=lambda self: self.env.user.company_id
+ .currency_id.id)
+ state = fields.Selection([('draft', 'Draft'),
+ ('reserve', 'Reserved'),
+ ('admit', 'Admitted'), ('invoice', 'Invoiced'),
+ ('dis', 'Discharge')],
+ string='State', readonly=True,
+ help='State of inpatient',
+ default="draft")
+ bed_rent_amount = fields.Monetary(string="Total Bed Rent",
+ help='Total rent '
+ 'for stayed '
+ 'days',
+ compute='_compute_bed_rent_amount',
+ copy=False)
+ invoice_id = fields.Many2one('account.move', string='Invoice',
+ help='Invoice id of the inpatient', copy=False)
+ admit_days = fields.Integer(string='Days',
+ help='Number of days the inpatient admitted',
+ compute='_compute_admit_days',
+ copy=False)
+ bed_type = fields.Selection([('gatch', 'Gatch Bed'),
+ ('electric', 'Electric'),
+ ('stretcher', 'Stretcher'),
+ ('low', 'Low Bed'),
+ ('air', 'Low Air Loss'),
+ ('circo', 'Circo Electric'),
+ ('clinitron', 'Clinitron'),
+ ], string="Bed Type",
+ help='Indicates the type of bed')
+ is_ward = fields.Selection([('ward', 'Ward'), ('room', 'Room')],
+ string='Room/Ward',
+ help='Choose where the patient is admitted to')
+ payment_ids = fields.One2many('inpatient.payment',
+ 'inpatient_id',
+ string='Payment Details',
+ help='Payment details of the patient')
+ is_invoice = fields.Boolean(string='Is Invoice',
+ help='View invoice button will be visible if '
+ 'this field is true')
+ prescription_ids = fields.One2many('prescription.line',
+ 'inpatient_id',
+ string='Prescription',
+ help='Medical prescriptions of patient')
+ enable_outpatient = fields.Boolean(string='Prescription History',
+ help='If checked, the prescription '
+ 'history of the patient will be '
+ 'added')
+ lab_test_ids = fields.One2many('patient.lab.test',
+ 'inpatient_id',
+ string='Lab Test',
+ help='Lab tests of the inpatient')
+ test_count = fields.Integer(string='Test Created',
+ help='Number of tests of the inpatient',
+ compute='_compute_test_count')
+ test_ids = fields.One2many('patient.lab.test',
+ 'inpatient_id', string='Test Line',
+ help='Details of the lab test')
+ surgery_ids = fields.One2many('inpatient.surgery',
+ 'inpatient_id',
+ string='Surgery/Operation',
+ help='Surgery details of the patient')
+ room_rent = fields.Monetary(string='Rent per day', help='Rent for the room',
+ related='room_id.rent')
+ room_rent_amount = fields.Monetary(string="Total Room Rent",
+ compute='_compute_room_rent_amount',
+ help='Total rent for the room',
+ copy=False)
+
+ @api.model
+ def create(self, vals):
+ """Sequence number generation"""
+ if vals.get('name', 'New') == 'New':
+ vals['name'] = self.env['ir.sequence'].next_by_code(
+ 'hospital.inpatient') or 'New'
+ return super().create(vals)
+
+ @api.depends('test_ids')
+ def _compute_test_count(self):
+ """Method for computing test count"""
+ self.test_count = self.env['lab.test.line'].sudo().search_count(
+ [('id', 'in', self.test_ids.ids)])
+
+ def _compute_admit_days(self):
+ """Method for computing admit days"""
+ if self.hosp_date:
+ if self.discharge_date:
+ self.admit_days = (self.discharge_date - self.hosp_date +
+ datetime.timedelta(days=1)).days
+ else:
+ self.admit_days = (fields.date.today() - self.hosp_date +
+ datetime.timedelta(days=1)).days
+
+ @api.depends('hosp_date', 'discharge_date',
+ 'admit_days', 'room_id')
+ def _compute_room_rent_amount(self):
+ """Method for computing room rent amount"""
+ if self.hosp_date:
+ if self.discharge_date:
+ self.admit_days = (self.discharge_date - self.hosp_date +
+ datetime.timedelta(days=1)).days
+ self.room_rent_amount = self.room_id.rent * self.admit_days
+ else:
+ self.admit_days = (fields.date.today() - self.hosp_date +
+ datetime.timedelta(days=1)).days
+ self.room_rent_amount = self.room_id.rent * self.admit_days
+ self.room_rent_amount = self.room_id.rent * self.admit_days
+
+ @api.depends('hosp_date', 'discharge_date', 'room_rent_amount',
+ 'admit_days')
+ def _compute_bed_rent_amount(self):
+ """Method for computing bed rent amount"""
+ if self.hosp_date:
+ if self.discharge_date:
+ self.admit_days = (self.discharge_date - self.hosp_date +
+ datetime.timedelta(days=1)).days
+ self.bed_rent_amount = self.bed_id.bed_rent * self.admit_days
+ else:
+ self.admit_days = (fields.date.today() - self.hosp_date +
+ datetime.timedelta(days=1)).days
+ self.bed_rent_amount = self.bed_id.bed_rent * self.admit_days
+ else:
+ self.bed_rent_amount = self.bed_id.bed_rent
+
+ @api.onchange('enable_outpatient')
+ def _onchange_enable_outpatient(self):
+ """Method for adding prescription lines of patient"""
+ self.prescription_ids = False
+ if self.enable_outpatient:
+ outpatient_id = self.env['hospital.outpatient'].sudo().search(
+ [('patient_id', '=', self.patient_id.id)])
+ self.sudo().write({
+ 'prescription_ids': [(0, 0, {
+ 'medicine_id': rec.medicine_id.id,
+ 'quantity': rec.quantity,
+ 'no_intakes': rec.no_intakes,
+ 'note': rec.note,
+ 'time': rec.time,
+ }) for rec in outpatient_id.prescription_ids]
+ })
+
+ @api.onchange('bed_type')
+ def _onchange_bed_type(self):
+ """Method for filtering beds according to the bed type"""
+ return {'domain': {
+ 'bed_id': [
+ ('bed_type', '=', self.bed_type),
+ ('state', '=', 'avail')
+ ], 'room_id': [
+ ('bed_type', '=', self.bed_type),
+ ('state', '=', 'avail')
+ ]}}
+
+ def action_view_invoice(self):
+ """Method for viewing Invoice"""
+ self.ensure_one()
+ return {
+ 'name': 'inpatient Invoice',
+ 'view_mode': 'tree,form',
+ 'res_model': 'account.move',
+ 'type': 'ir.actions.act_window',
+ 'domain': [('ref', '=', self.name)],
+ 'context': "{'create':False}"
+ }
+
+ def action_view_tests(self):
+ """Returns all lab tests"""
+ return {
+ 'name': 'Lab Tests',
+ 'res_model': 'patient.lab.test',
+ 'view_mode': 'tree,form',
+ 'type': 'ir.actions.act_window',
+ 'domain': [('inpatient_id', '=', self.id)]
+ }
+
+ def action_create_lab_test(self):
+ """Function for creating lab test"""
+ return {
+ 'name': 'Create Lab Test',
+ 'res_model': 'lab.test.line',
+ 'view_mode': 'form',
+ 'views': [[False, 'form']],
+ 'target': 'current',
+ 'type': 'ir.actions.act_window',
+ 'context': {
+ 'default_patient_id': self.patient_id.id,
+ 'default_doctor_id': self.attending_doctor_id.id,
+ 'default_patient_type': 'inpatient',
+ 'default_ip_id': self.id
+ }
+ }
+
+ def action_view_test(self):
+ """View test details"""
+ return {
+ 'name': 'Created Tests',
+ 'res_model': 'lab.test.line',
+ 'view_mode': 'tree,form',
+ 'target': 'current',
+ 'type': 'ir.actions.act_window',
+ 'domain': [
+ ('patient_type', '=', 'inpatient'),
+ ('ip_id', '=', self.id)
+ ]
+ }
+
+ def action_reserve(self):
+ """Method for inpatient reservation"""
+ if self.bed_id:
+ self.bed_id.state = 'not'
+ if self.room_id:
+ self.room_id.state = 'reserve'
+ self.sudo().write({
+ 'state': "reserve"
+ })
+
+ def action_admit(self):
+ """Method for patient admission"""
+ if self.bed_id:
+ self.bed_id.state = 'not'
+ if self.room_id:
+ self.room_id.state = 'not'
+ self.sudo().write({
+ 'state': "admit"
+ })
+
+ def action_discharge(self):
+ """Method for patient discharge"""
+ if self.bed_id:
+ self.bed_id.state = 'avail'
+ if self.room_id:
+ self.room_id.state = 'avail'
+ self.sudo().write({
+ 'state': "dis"
+ })
+ self.active = False
+
+ def action_invoice(self):
+ """Method for creating invoice"""
+ self.is_invoice = True
+ self.state = 'invoice'
+ inv_line_list = []
+ invoice = self.env['account.move.line'].sudo().search(
+ [('move_id.partner_id', '=', self.patient_id.id),
+ ('move_id.state', '=', 'draft'),
+ ('group_tax_id', '=', False),
+ ('date_maturity', '=', False),
+ ('move_id.move_type', '=', 'out_invoice')])
+ for rec in self:
+ if rec.bed_rent_amount:
+ inv_line_list.append((0, 0, {'name': 'Room/Bed Rent Amount',
+ 'price_unit': rec.bed_rent_amount,
+ 'quantity': rec.admit_days,
+ }))
+ elif rec.room_rent_amount:
+ inv_line_list.append((0, 0, {'name': 'Room/Bed Rent Amount',
+ 'price_unit': rec.room_rent_amount,
+ 'quantity': rec.admit_days,
+ }))
+ for line in rec.payment_ids:
+ inv_line_list.append((0, 0, {'name': line.name,
+ 'price_unit': line.subtotal,
+ 'quantity': 1,
+ 'tax_ids': line.tax_ids
+ }))
+ for line in self.test_ids:
+ if not line.invoice_id:
+ inv_line_list.append((0, 0, {
+ 'name': line.test_id.name,
+ 'price_unit': line.total_price,
+ 'quantity': 1
+ }))
+ for line in self.prescription_ids:
+ inv_line_list.append((0, 0, {
+ 'name': line.medicine_id.name,
+ 'price_unit': line.medicine_id.list_price,
+ 'quantity': line.quantity
+ }))
+ if invoice:
+ for line in invoice.read(
+ ['name', 'price_unit', 'quantity']):
+ inv_line_list.append((0, 0, {'name': line['name'],
+ 'price_unit': line[
+ 'price_unit'],
+ 'quantity': line['quantity']}))
+ move = self.env['account.move'].sudo().create({
+ 'move_type': 'out_invoice',
+ 'date': fields.Date.today(),
+ 'ref': self.name,
+ 'invoice_date': fields.Date.today(),
+ 'partner_id': self.patient_id.id,
+ 'line_ids': inv_line_list
+ })
+ self.invoice_id = move.id
+ for rec in invoice:
+ rec.move_id.button_cancel()
+ return {
+ 'name': 'Invoice',
+ 'res_model': 'account.move',
+ 'view_mode': 'form',
+ 'view_Id': self.env.ref('account.view_move_form').id,
+ 'context': "{'move_type':'out_invoice'}",
+ 'type': 'ir.actions.act_window',
+ 'res_id': move.id
+ }
+
+ def create_new_in_patient(self, domain):
+ """Create in-patient from receptionist dashboard"""
+ if domain:
+ self.sudo().create({
+ 'patient_id': domain['patient_id'],
+ 'reason': domain['reason_of_admission'],
+ 'type_admission': domain['admission_type'],
+ 'attending_doctor_id': domain['attending_doctor_id'],
+ })
+
+ def fetch_inpatient(self, domain):
+ """Returns inpatient details to display on the doctor's dashboard"""
+ if domain:
+ return self.env['hospital.inpatient'].sudo().search(
+ ['|', '|', '|', '|', ('name', 'ilike', domain),
+ ('patient_id.name', 'ilike', domain),
+ ('hosp_date', 'ilike', domain),
+ ('discharge_date', 'ilike', domain),
+ ('state', 'ilike', domain)]).read(
+ ['name', 'patient_id', 'ward_id', 'bed_id',
+ 'hosp_date', 'discharge_date', 'type_admission',
+ 'attending_doctor_id',
+ 'state'])
+ else:
+ return self.env['hospital.inpatient'].sudo().search_read(
+ fields=['name', 'patient_id', 'ward_id', 'bed_id', 'hosp_date',
+ 'discharge_date', 'attending_doctor_id', 'state'])
+
+ def action_print_prescription(self):
+ """Method for printing prescription"""
+ data = False
+ p_list = []
+ for rec in self.prescription_ids:
+ p_list.append({
+ 'medicine': rec.medicine_id.name,
+ 'intake': rec.no_intakes,
+ 'time': rec.time.capitalize(),
+ 'quantity': rec.quantity,
+ 'note': rec.note.capitalize(),
+ })
+ data = {
+ 'datas': p_list,
+ 'date': fields.date.today(),
+ 'patient_name': self.patient_id.name,
+ 'doctor_name': self.attending_doctor_id.name,
+ }
+ return self.env.ref(
+ 'base_hospital_management.action_report_patient_prescription'). \
+ report_action(self, data=data)
+
+ @api.model
+ def hospital_inpatient_list(self):
+ """Returns list of inpatients to doctor's dashboard"""
+ patient_list = []
+ patients = self.sudo().search([])
+ patient_type = {'emergency': 'Emergency Admission',
+ 'routine': 'Routine Admission'}
+ for rec in patients:
+ patient_list.append({
+ 'id': rec.id,
+ 'name': rec.name,
+ 'patient_id': rec.patient_id.name,
+ 'bed_id': rec.bed_id.name,
+ 'ward_id': rec.ward_id.ward_no,
+ 'room_id': rec.room_id,
+ 'hosp_date': rec.hosp_date,
+ 'attending_doctor_id': rec.attending_doctor_id._origin.name,
+ 'admission_type': patient_type[rec.type_admission],
+ 'discharge_date': rec.discharge_date
+ })
+ data = {
+ 'record': patient_list
+ }
+ return data
diff --git a/base_hospital_management/models/hospital_insurance.py b/base_hospital_management/models/hospital_insurance.py
new file mode 100755
index 000000000..8c12f9578
--- /dev/null
+++ b/base_hospital_management/models/hospital_insurance.py
@@ -0,0 +1,38 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 HospitalInsurance(models.Model):
+ """Class holding insurance details"""
+ _name = 'hospital.insurance'
+ _description = 'Hospital Insurance'
+
+ name = fields.Char(string='Provider', help='Name of the insurance provider')
+ currency_id = fields.Many2one('res.currency', string='Currency',
+ help='Currency in which insurance will be '
+ 'calculated',
+ default=lambda self: self.env.user.company_id
+ .currency_id.id,
+ required=True)
+ total_coverage = fields.Monetary(string='Total Coverage',
+ help='Total coverage of the insurance')
diff --git a/base_hospital_management/models/hospital_laboratory.py b/base_hospital_management/models/hospital_laboratory.py
new file mode 100755
index 000000000..4e3a30147
--- /dev/null
+++ b/base_hospital_management/models/hospital_laboratory.py
@@ -0,0 +1,65 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 HospitalLaboratory(models.Model):
+ """Class holding laboratory details"""
+ _name = 'hospital.laboratory'
+ _description = 'Hospital Laboratory'
+
+ notes = fields.Text(string='Notes', help='Notes regarding the laboratory')
+ image_130 = fields.Image(max_width=128, max_height=128, string='Image',
+ help='Image of the laboratory')
+ phone = fields.Char(string='Phone', help='Phone number of laboratory')
+ mobile = fields.Char(string='Mobile', help='Mobile number of'
+ ' laboratory')
+ email = fields.Char(string='Email', help='Email of the laboratory')
+ street = fields.Char(string='Street', help='Street name of lab')
+ street2 = fields.Char(string='Street2', help='Street2 name of lab')
+ zip = fields.Char(string='Zip', help='Zip code of lab')
+ city = fields.Char(string='City', help="City of lab")
+ state_id = fields.Many2one("res.country.state",
+ string='State',
+ help='State of lab')
+ country_id = fields.Many2one('res.country',
+ related='state_id.country_id',
+ string='Country',
+ help='Country name of lab')
+ note = fields.Text(string='Note', help='Notes regarding lab')
+ name = fields.Char(string='Lab Sequence', help='Sequence number for lab',
+ copy=False,
+ readonly=True, index=1, default=lambda self: 'New')
+ technician_id = fields.Many2one('hr.employee',
+ string="Lab in charge",
+ domain=[
+ ('job_title', '=', 'Lab Technician')],
+ help='Name of the lab technician who has '
+ 'the in charge')
+
+ @api.model
+ def create(self, vals):
+ """Method for creating lab sequence number"""
+ if vals.get('name', 'New') == 'New':
+ vals['name'] = self.env['ir.sequence'].next_by_code(
+ 'laboratory.sequence') or 'New'
+ return super().create(vals)
diff --git a/base_hospital_management/models/hospital_outpatient.py b/base_hospital_management/models/hospital_outpatient.py
new file mode 100755
index 000000000..6ceb15869
--- /dev/null
+++ b/base_hospital_management/models/hospital_outpatient.py
@@ -0,0 +1,318 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 base64
+from odoo import api, fields, models
+from odoo.exceptions import ValidationError
+
+
+class HospitalOutpatient(models.Model):
+ """Class holding Outpatient details"""
+ _name = 'hospital.outpatient'
+ _description = 'Hospital Outpatient'
+ _rec_name = 'op_reference'
+ _inherit = 'mail.thread'
+ _order = 'op_date desc'
+
+ op_reference = fields.Char(string="OP Reference", readonly=True,
+ default='New',
+ help='Op reference number of the patient')
+ patient_id = fields.Many2one('res.partner',
+ domain=[('patient_seq', 'not in',
+ ['New', 'Employee', 'User'])],
+ string='Patient ID', help='Id of the patient',
+ required=True)
+ doctor_id = fields.Many2one('doctor.allocation',
+ string='Doctor',
+ help='Select the doctor',
+ required=True,
+ domain=[('slot_remaining', '>', 0),
+ ('date', '=', fields.date.today()),
+ ('state', '=', 'confirm')])
+ op_date = fields.Date(default=fields.date.today(), string='Date',
+ help='Date of OP')
+ reason = fields.Text(string='Reason', help='Reason for visiting hospital')
+ test_count = fields.Integer(string='Test Created',
+ help='Number of tests created for the patient',
+ compute='_compute_test_count')
+ test_ids = fields.One2many('lab.test.line', 'op_id',
+ string='Tests',
+ help='Tests for the patient')
+ state = fields.Selection(
+ [('draft', 'Draft'), ('op', 'OP'), ('inpatient', 'In Patient'),
+ ('invoice', 'Invoiced'), ('cancel', 'Canceled')],
+ default='draft', string='State', help='State of the outpatient')
+ prescription_ids = fields.One2many('prescription.line',
+ 'outpatient_id',
+ string='Prescription',
+ help='Prescription for the patient')
+ invoiced = fields.Boolean(default=False, string='Invoiced',
+ help='True for invoiced')
+ invoice_id = fields.Many2one('account.move', copy=False,
+ string='Invoice',
+ help='Invoice of the patient')
+ attachment_id = fields.Many2one('ir.attachment',
+ string='Attachment',
+ help='Attachments related to the'
+ ' outpatient')
+ active = fields.Boolean(string='Active', help='True for active patients',
+ default=True)
+ slot = fields.Float(string='Slot', help='Slot for the patient',
+ copy=False, readonly=True)
+ is_sale_created = fields.Boolean(string='Sale Created',
+ help='True if sale order created')
+
+ @api.model
+ def create(self, vals):
+ """Op number generator"""
+ if vals.get('op_reference', 'New') == 'New':
+ last_op = self.search([
+ ('doctor_id', '=', vals.get('doctor_id')),
+ ('op_reference', '!=', 'New'),
+ ], order='create_date desc', limit=1)
+ if last_op:
+ last_number = int(last_op.op_reference[2:])
+ new_number = last_number + 1
+ vals['op_reference'] = f'OP{str(new_number).zfill(3)}'
+ else:
+ vals['op_reference'] = 'OP001'
+ if self.search([
+ ('patient_id', '=', vals['patient_id']),
+ ('doctor_id', '=', vals['doctor_id'])
+ ]):
+ raise ValidationError(
+ 'An OP already exists for this patient under the specified '
+ 'allocation')
+ return super().create(vals)
+
+ @api.depends('test_ids')
+ def _compute_test_count(self):
+ """Computes the value of test count"""
+ self.test_count = len(self.test_ids.ids)
+
+ @api.onchange('op_date')
+ def _onchange_op_date(self):
+ """Method for updating the doamil of doctor_id"""
+ self.doctor_id = False
+ return {'domain': {'doctor_id': [('slot_remaining', '>', 0),
+ ('date', '=', self.op_date),
+ ('state', '=', 'confirm'), (
+ 'patient_type', 'in',
+ [False, 'outpatient'])]}}
+
+ @api.model
+ def action_row_click_data(self, op_reference):
+ """Returns data to be displayed on clicking op row"""
+ op_record = self.env['hospital.outpatient'].sudo().search(
+ [('op_reference', '=', op_reference),
+ ('active', 'in', [True, False])])
+ op_data = [op_reference, op_record.patient_id.patient_seq,
+ op_record.patient_id.name, str(op_record.op_date),
+ op_record.slot, op_record.reason,
+ op_record.doctor_id.doctor_id.name,
+ op_record.is_sale_created]
+ medicines = []
+ for rec in op_record.prescription_ids:
+ medicines.append(
+ [rec.medicine_id.name, rec.no_intakes, rec.time, rec.note,
+ rec.quantity, rec.medicine_id.id])
+ values = {
+ 'op_data': op_data,
+ 'medicines': medicines
+ }
+ return values
+
+ @api.model
+ def create_medicine_sale_order(self, order_id):
+ """Method for creating sale order for medicines"""
+ order = self.sudo().search([('op_reference', 'ilike', order_id)])
+ sale_order = self.env['sale.order'].sudo().create({
+ 'partner_id': order.patient_id.id,
+ })
+ for i in order.prescription_ids:
+ self.env['sale.order.line'].sudo().create({
+ 'product_id': i.medicine_id.id,
+ 'product_uom_qty': i.quantity,
+ 'order': sale_order.id,
+ })
+ self.create_invoice()
+
+ @api.model
+ def create_file(self, rec_id):
+ """Method for creating prescription"""
+ record = self.env['hospital.outpatient'].sudo().browse(rec_id)
+ p_list = []
+ data = False
+ for rec in record.prescription_ids:
+ p_list.append({
+ 'medicine': rec.medicine_id.name,
+ 'intake': rec.no_intakes,
+ 'time': rec.time.capitalize(),
+ 'quantity': rec.quantity,
+ 'note': rec.note.capitalize() if rec.note else '',
+ })
+ data = {
+ 'datas': p_list,
+ 'date': record.op_date,
+ 'patient_name': record.patient_id.name,
+ 'doctor_name': record.doctor_id.doctor_id.name,
+ }
+ pdf = self.env['ir.actions.report'].sudo()._render_qweb_pdf(
+ 'base_hospital_management.action_report_patient_prescription',
+ rec_id, data=data)
+ record.attachment_id = self.env['ir.attachment'].sudo().create({
+ 'datas': base64.b64encode(pdf[0]),
+ 'name': "Prescription",
+ 'type': 'binary',
+ 'res_model': 'hospital.outpatient',
+ 'res_id': rec_id,
+ })
+ return {
+ 'url': f'/web/content'
+ f'/{record.attachment_id.id}?download=true&'
+ f';access_token=',
+ }
+
+ @api.model
+ def create_new_out_patient(self, kw):
+ """Create out patient from receptionist dashboard"""
+ if kw['id']:
+ partner = self.env['res.partner'].sudo().search(
+ ['|', ('barcode', '=', kw['id']),
+ ('phone', '=', kw['op_phone'])])
+ self.sudo().create({
+ 'patient_id': partner.id,
+ 'op_date': kw['date'],
+ 'reason': kw['reason'],
+ 'slot': kw['slot'],
+ 'doctor_id': kw['doctor'],
+ })
+
+ def action_create_lab_test(self):
+ """Button action for creating a lab test"""
+ return {
+ 'name': 'Create Lab Test',
+ 'res_model': 'lab.test.line',
+ 'view_mode': 'form',
+ 'views': [[False, 'form']],
+ 'target': 'current',
+ 'type': 'ir.actions.act_window',
+ 'context': {
+ 'default_patient_id': self.patient_id.id,
+ 'default_doctor_id': self.doctor_id.id,
+ 'default_patient_type': 'outpatient',
+ 'default_op_id': self.id
+ }
+ }
+
+ def action_view_test(self):
+ """Method for viewing all lab tests"""
+ return {
+ 'name': 'Created Tests',
+ 'res_model': 'lab.test.line',
+ 'view_mode': 'tree,form',
+ 'target': 'current',
+ 'type': 'ir.actions.act_window',
+ 'domain': [
+ ('patient_type', '=', 'outpatient'),
+ ('op_id', '=', self.id)
+ ]
+ }
+
+ def action_convert_to_inpatient(self):
+ """Converts an outpatient to inpatient"""
+ self.state = 'inpatient'
+ return {
+ 'name': 'Convert to Inpatient',
+ 'res_model': 'hospital.inpatient',
+ 'view_mode': 'form',
+ 'target': 'current',
+ 'type': 'ir.actions.act_window',
+ 'context': {
+ 'default_patient_id': self.patient_id.id,
+ 'default_attending_doctor_id': self.doctor_id.doctor_id.id,
+ }
+ }
+
+ def action_op_cancel(self):
+ """Button action for cancelling an op"""
+ self.state = 'cancel'
+
+ def action_confirm(self):
+ """Button action for confirming an op"""
+ if self.doctor_id.latest_slot == 0:
+ self.slot = self.doctor_id.work_from
+ else:
+ self.slot = self.doctor_id.latest_slot + self.doctor_id.time_avg
+ self.doctor_id.latest_slot = self.slot
+ self.state = 'op'
+
+ def create_invoice(self):
+ """Method for creating invoice"""
+ self.state = 'invoice'
+ self.invoice_id = self.env['account.move'].sudo().create({
+ 'move_type': 'out_invoice',
+ 'date': fields.Date.today(),
+ 'invoice_date': fields.Date.today(),
+ 'partner_id': self.patient_id.id,
+ 'invoice_line_ids': [(
+ 0, 0, {
+ 'name': 'Consultation fee',
+ 'quantity': 1,
+ 'price_unit': self.doctor_id.doctor_id.consultancy_charge,
+ }
+ )]
+ })
+ self.invoiced = True
+
+ def action_view_invoice(self):
+ """Method for viewing invoice"""
+ return {
+ 'name': 'Invoice',
+ 'domain': [('id', '=', self.invoice_id.id)],
+ 'type': 'ir.actions.act_window',
+ 'res_model': 'account.move',
+ 'view_mode': 'tree,form',
+ 'context': {'create': False},
+ }
+
+ def action_print_prescription(self):
+ """Method for printing prescription"""
+ data = False
+ p_list = []
+ for rec in self.prescription_ids:
+ datas = {
+ 'medicine': rec.medicine_id.name,
+ 'intake': rec.no_intakes,
+ 'time': rec.time.capitalize(),
+ 'quantity': rec.quantity,
+ 'note': rec.note.capitalize(),
+ }
+ p_list.append(datas)
+ data = {
+ 'datas': p_list,
+ 'date': self.op_date,
+ 'patient_name': self.patient_id.name,
+ 'doctor_name': self.doctor_id.doctor_id.name,
+ }
+ return self.env.ref(
+ 'base_hospital_management.action_report_patient_prescription'). \
+ report_action(self, data=data)
diff --git a/base_hospital_management/models/hospital_pharmacy.py b/base_hospital_management/models/hospital_pharmacy.py
new file mode 100755
index 000000000..caf55e2e2
--- /dev/null
+++ b/base_hospital_management/models/hospital_pharmacy.py
@@ -0,0 +1,160 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 HospitalPharmacy(models.Model):
+ """Class holding Pharmacy details."""
+ _name = 'hospital.pharmacy'
+ _description = 'Pharmacy'
+
+ name = fields.Char(string="Name", help='Name of the pharmacy',
+ required="True")
+ pharmacist_id = fields.Many2one('hr.employee',
+ string="Pharmacist",
+ help='Name of the pharmacist',
+ domain=[
+ ('job_id.name', '=', 'Pharmacist')])
+ phone = fields.Char(string='Phone', help='Phone number of the pharmacy')
+ mobile = fields.Char(string='Mobile', help='Mobile number of the pharmacy')
+ email = fields.Char(string='Email', help='Email of the pharmacy')
+ street = fields.Char(string='Street', help='Street of pharmacy')
+ street2 = fields.Char(string='Street2', help='Street2 of pharmacy')
+ zip = fields.Char(string='Zip', help='Zip code of pharmacy')
+ city = fields.Char(string='City', help='City of pharmacy')
+ state_id = fields.Many2one("res.country.state", string='State',
+ help='State of pharmacy')
+ country_id = fields.Many2one('res.country', string='Country',
+ help='Country of pharmacy')
+ notes = fields.Text(string='Notes', help='Notes regarding pharmacy')
+ image_129 = fields.Image(string='Image', help='Image of pharmacy',
+ max_width=128, max_height=128)
+ active = fields.Boolean(string='Active', help='True for active pharmacy',
+ default=True)
+ medicine_ids = fields.One2many('pharmacy.medicine',
+ 'pharmacy_id',
+ string='Pharmacy',
+ help='Indicates the medicines in the '
+ 'pharmacy')
+ sales_team_id = fields.Many2one('crm.team', string='Sales Team',
+ help='Choose the sales-team for the'
+ ' pharmacy')
+
+ @api.model
+ def create(self, vals):
+ """Method for creating CRM team"""
+ team_id = self.env['crm.team'].sudo().create({
+ 'name': vals['name'] + ' Pharmacy Team',
+ 'company_id': False,
+ 'user_id': self.env.uid
+ })
+ vals['sales_team_id'] = team_id.id
+ return super().create(vals)
+
+ @api.model
+ def create_sale_order(self, **kwargs):
+ """Creating sale order from pharmacy dashboard"""
+ if 'op' not in kwargs.keys():
+ patient_id = self.env['res.partner'].sudo().create({
+ 'name': kwargs['name'],
+ })
+ else:
+ patient_id = self.env['hospital.outpatient'].sudo().search(
+ [('op_reference', '=', kwargs['op'])]).patient_id
+ pharmacy_sale_order = self.env['sale.order'].sudo().create({
+ 'partner_id': patient_id.id,
+ })
+ for rec in kwargs['products']:
+ pharmacy_sale_order.sudo().write({
+ 'order_line': [(0, 0, {
+ 'product_id': int(
+ rec['prod']) if 'op' not in kwargs.keys() else
+ self.env[
+ 'product.product'].search(
+ [('product_tmpl_id', '=', int(rec['prod']))]).id,
+ 'product_uom_qty': float(rec['qty']),
+ 'price_unit': float(
+ rec['price']) if 'price' in rec.keys() else
+ self.env[
+ 'product.product'].search(
+ [('product_tmpl_id', '=',
+ int(rec['prod']))]).list_price
+ })]
+ })
+ pharmacy_sale_order.action_confirm()
+ if 'op' in kwargs.keys():
+ self.env['hospital.outpatient'].sudo().search(
+ [('op_reference', '=', kwargs['op'])]).write(
+ {
+ 'is_sale_created': True
+ })
+ return pharmacy_sale_order
+
+ @api.model
+ def company_currency(self):
+ """Currency symbol of current company"""
+ return self.env.user.company_id.currency_id.symbol
+
+ @api.model
+ def tax_amount(self, kw):
+ """Amount in tax of selected product in pharmacy"""
+ return {
+ 'amount': self.env['account.tax'].sudo().browse(kw).amount
+ }
+
+ def action_get_inventory(self):
+ """Inventory adjustment for medicine"""
+ med_list = []
+ for med in self.medicine_ids.product_id:
+ for product in self.env['product.product'].sudo().search([]):
+ if med.id == product.product_tmpl_id.id:
+ med_list.append(product.id)
+ return {
+ 'name': 'medicine',
+ 'domain': ['&', ('product_id', 'in', med_list),
+ ('location_id.usage', '=', 'internal')],
+ 'type': 'ir.actions.act_window',
+ 'res_model': 'stock.quant',
+ 'view_id': self.env.ref(
+ 'stock.view_stock_quant_tree_inventory_editable').id,
+ 'view_mode': 'tree',
+ }
+
+ def action_get_sale_order(self):
+ """Sale order view of medicine"""
+ return {
+ 'name': 'Sales',
+ 'res_model': 'sale.order',
+ 'view_mode': 'tree,form',
+ 'domain': [('team_id', '=', self.sales_team_id.id)],
+ 'type': 'ir.actions.act_window',
+ 'context': {'default_team_id': self.sales_team_id.id}
+ }
+
+ def fetch_sale_orders(self):
+ """Method to fetch all sale orders for displaying on pharmacy
+ dashboard"""
+ return self.env['sale.order'].search_read(
+ [('partner_id.patient_seq', 'not in', ['New', 'Employee',
+ 'User'])],
+ fields=['name', 'create_date', 'partner_id', 'amount_total',
+ 'state'])
diff --git a/base_hospital_management/models/hospital_vaccination.py b/base_hospital_management/models/hospital_vaccination.py
new file mode 100755
index 000000000..43f61e653
--- /dev/null
+++ b/base_hospital_management/models/hospital_vaccination.py
@@ -0,0 +1,155 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 datetime import timedelta
+from odoo import api, fields, models
+
+
+class HospitalVaccination(models.Model):
+ """Class holding Vaccination details"""
+ _name = 'hospital.vaccination'
+ _description = "Vaccination Details"
+ _order = 'name desc'
+
+ name = fields.Char(string='Vaccination Reference', copy=False,
+ readonly=True, index=True, help='Name of vaccination',
+ default=lambda self: 'New')
+ patient_id = fields.Many2one('res.partner',
+ domain=[('patient_seq', 'not in',
+ ['New', 'Employee', 'User'])],
+ required=True,
+ string="Patient", help='Choose the patient')
+ vaccine_date = fields.Date(string='Vaccination Date', help='Date of '
+ 'vaccination',
+ default=fields.date.today())
+ dose = fields.Float(string='Dose', help='Dose of the vaccine')
+ vaccine_product_id = fields.Many2one('product.template',
+ domain="[('vaccine_ok', '=', True)]",
+ string="Vaccine", help='Choose the '
+ 'vaccine',
+ required=True)
+ vaccine_price = fields.Float(related='vaccine_product_id.list_price',
+ string="Price", help='Price of vaccine')
+ sale_order_id = fields.Many2one('sale.order',
+ string='Sale Order',
+ help='Sale order for the vaccine')
+ sold = fields.Boolean(string='Sold', help='True if sale order created')
+ certificate = fields.Binary(string="Certificate", help='Vaccination '
+ 'certificate')
+ attachment_id = fields.Many2one('ir.attachment',
+ string='Attachment',
+ help='Attachments added to the vaccination')
+ recurring_vaccine = fields.Boolean(string='Recurring Vaccine',
+ help='True for recurring vaccinations')
+ total_vaccine = fields.Integer(string="Total Dose",
+ help='Total number of vaccines')
+ next_vaccine_days = fields.Integer(string="Next Vaccine (In Days)",
+ help='The number of days to next '
+ 'vaccine')
+ next_vaccine = fields.Date(string="Next Vaccination Date",
+ help='Date of next '
+ 'vaccine',
+ readonly=True)
+
+ @api.model
+ def create(self, vals):
+ """Inherits create method for creating the vaccination sequence"""
+ if vals.get('name', 'New') == 'New':
+ vals['name'] = self.env['ir.sequence'].next_by_code(
+ 'vaccination.sequence') or 'New'
+ return super().create(vals)
+
+ @api.onchange('next_vaccine_days')
+ def _onchange_next_vaccine_days(self):
+ """Method for updating the field next_vaccine according to the value
+ of next_vaccine_days"""
+ if self.next_vaccine_days:
+ self.sudo().write({'next_vaccine': fields.Date.today() + timedelta(
+ self.next_vaccine_days)})
+
+ def action_create_so(self):
+ """Method for creating the sale order for vaccines"""
+ product_id = self.env['product.product'].sudo().search([
+ ('product_tmpl_id', '=', self.vaccine_product_id.id)
+ ])
+ sale = self.env['sale.order'].search([
+ ('partner_id.id', '=', self.patient_id.id),
+ ('state', '=', 'draft')], limit=1)
+ if sale:
+ sale.sudo().write({
+ 'order_line': [(
+ 0, 0, {
+ 'product_id': product_id[0].id,
+ 'name': self.vaccine_product_id.name,
+ 'price_unit': self.vaccine_price,
+ 'product_uom_qty': self.dose
+ }
+ )]
+ })
+ else:
+ sale = self.env['sale.order'].sudo().create({
+ 'partner_id': self.patient_id.id,
+ 'date_order': fields.Date.today(),
+ 'order_line': [(0, 0, {
+ 'product_id': product_id[0].id,
+ 'name': self.vaccine_product_id.name,
+ 'price_unit': self.vaccine_price,
+ 'product_uom_qty': self.dose
+ })]
+ })
+ self.sold = True
+ self.sale_order_id = sale.id
+
+ def get_sale_order(self):
+ """Smart button action for viewing corresponding sale orders"""
+ return {
+ 'name': 'Sale order',
+ 'res_model': 'sale.order',
+ 'view_mode': 'form',
+ 'type': 'ir.actions.act_window',
+ 'res_id': self.sale_order_id.id
+ }
+
+ @api.model
+ def fetch_vaccination_data(self, **kwargs):
+ """Method for fetching vaccine data"""
+ data = self.sudo().search(kwargs['domain'])
+ context = []
+ for rec in data:
+ self.env.cr.execute(
+ f"""SELECT id FROM ir_attachment WHERE
+ res_id = {rec.id} and res_model='hospital.vaccination' """)
+ attachment_id = False
+ attachment = self.env.cr.dictfetchall()
+ if attachment:
+ attachment_id = attachment[0]['id']
+ context.append({
+ 'id': rec.id,
+ 'name': rec.name,
+ 'patient_id': [rec.patient_id.id,
+ rec.patient_id.name],
+ 'vaccine_product_id': rec.vaccine_product_id.name,
+ 'vaccine_price': rec.vaccine_price,
+ 'attachment_id': attachment_id,
+ 'view_id': self.env['ir.ui.view'].sudo().search([
+ ('name', '=', 'hospital.vaccination.view.form')]).id
+ })
+ return context
diff --git a/base_hospital_management/models/hospital_ward.py b/base_hospital_management/models/hospital_ward.py
new file mode 100755
index 000000000..f5a72c790
--- /dev/null
+++ b/base_hospital_management/models/hospital_ward.py
@@ -0,0 +1,76 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 HospitalWard(models.Model):
+ """Class holding Ward details"""
+ _name = 'hospital.ward'
+ _description = 'Hospital Ward'
+ _rec_name = 'ward_no'
+
+ ward_no = fields.Char(string="Name",
+ required="True", help='Number of the ward')
+ building_id = fields.Many2one('hospital.building',
+ string="Block", help='The building to '
+ 'which the ward '
+ 'corresponds to')
+ floor_no = fields.Integer(string="Floor No.", help='The floor to '
+ 'which the ward '
+ 'corresponds to')
+ note = fields.Text(string="Note", help='Note regarding the ward')
+ bed_count = fields.Integer(string="Count", compute="_compute_bed_count",
+ help='The bed count')
+ nurse_ids = fields.Many2many('hr.employee', string='Nurses',
+ domain="[('job_id','=','Nurse')]",
+ help='Nurses corresponds to the ward')
+ ward_facilities_ids = fields.Many2many('room.facility',
+ string='Facilities',
+ help='Facilities corresponds to '
+ 'ward.')
+ _sql_constraints = [('unique_ward', 'unique (ward_no)',
+ 'Ward number should be unique!')]
+
+ def _compute_bed_count(self):
+ """Method for computing bed count"""
+ for rec in self:
+ rec.bed_count = rec.env['hospital.bed'].sudo().search_count([(
+ 'ward_id', '=', rec.ward_no)])
+
+ @api.onchange('building_id')
+ def _onchange_building_id(self):
+ """Returns domain for the field bed_id"""
+ return {'domain': {
+ 'bed_id': [
+ ('ward_id', '=', self.id),
+ ]}}
+
+ def action_get_open_bed(self):
+ """Returns form view of bed"""
+ return {
+ 'name': 'Bed',
+ 'domain': [('ward_id', '=', self.ward_no)],
+ 'type': 'ir.actions.act_window',
+ 'res_model': 'hospital.bed',
+ 'view_mode': 'tree',
+ 'context': {'create': False},
+ }
diff --git a/base_hospital_management/models/hr_employee.py b/base_hospital_management/models/hr_employee.py
new file mode 100755
index 000000000..3f407b305
--- /dev/null
+++ b/base_hospital_management/models/hr_employee.py
@@ -0,0 +1,100 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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, _
+from odoo.exceptions import ValidationError
+
+
+class HrEmployee(models.Model):
+ """Inherited to add more fields and functions"""
+ _inherit = 'hr.employee'
+
+ doctor = fields.Boolean(string='Doctor', help='True for Doctors')
+ currency_id = fields.Many2one('res.currency', string='Currency',
+ help='Currency in which consultation fee '
+ 'is calculating',
+ default=lambda self: self.env.user.company_id
+ .currency_id.id,
+ required=True)
+ coach_id = fields.Many2one('hr.employee', string='Coach',
+ help='Name of the coach')
+ consultancy_charge = fields.Monetary(string="Consultation Charge",
+ help='Charge for consultation')
+ consultancy_type = fields.Selection([('resident', 'Residential'),
+ ('special', 'Specialist')],
+ string="Consultation Type",
+ help='Select the type of Consultation')
+ time_avg = fields.Float(string='Average Time for a Patient',
+ help="Average Consultation time "
+ "per Patient in minutes")
+ degree_ids = fields.Many2many('hospital.degree',
+ string="Degree",
+ help='Degrees of staff')
+ pharmacy_id = fields.Many2one('hospital.pharmacy',
+ string="Pharmacy",
+ help='Name of the pharmacy')
+ specialization_ids = fields.Many2many('doctor.specialization',
+ string="Specialization",
+ help="Doctors specialization for"
+ " an area")
+
+ def action_create_user(self):
+ """Updating employee field of res user to true"""
+ self.ensure_one()
+ if self.user_id:
+ raise ValidationError(_("This employee already has an user."))
+ return {
+ 'name': _('Create User'),
+ 'type': 'ir.actions.act_window',
+ 'res_model': 'res.users',
+ 'view_mode': 'form',
+ 'view_id': self.env.ref('hr.view_users_simple_form').id,
+ 'target': 'new',
+ 'context': {
+ 'default_create_employee_id': self.id,
+ 'default_name': self.name,
+ 'default_phone': self.work_phone,
+ 'default_mobile': self.mobile_phone,
+ 'default_login': self.work_email,
+ 'default_employee': True
+ }
+ }
+
+ def _inverse_work_contact_details(self):
+ """Override to prevent creating patient while creating a staff"""
+ for employee in self:
+ if not employee.work_contact_id:
+ employee.work_contact_id = self.env[
+ 'res.partner'].sudo().create(
+ {
+ 'email': employee.work_email,
+ 'mobile': employee.mobile_phone,
+ 'name': employee.name,
+ 'image_1920': employee.image_1920,
+ 'company_id': employee.company_id.id,
+ 'patient_seq': 'Employee'
+ })
+ else:
+ employee.work_contact_id.sudo().write({
+ 'email': employee.work_email,
+ 'mobile': employee.mobile_phone,
+ 'patient_seq': 'Employee'
+ })
diff --git a/base_hospital_management/models/inpatient_payment.py b/base_hospital_management/models/inpatient_payment.py
new file mode 100755
index 000000000..90c7b88c0
--- /dev/null
+++ b/base_hospital_management/models/inpatient_payment.py
@@ -0,0 +1,37 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 InpatientPayment(models.Model):
+ """Class holding Payment details of Inpatient"""
+ _name = 'inpatient.payment'
+ _description = "Inpatient Payments"
+
+ name = fields.Char(string='Name', help='Name of payment')
+ subtotal = fields.Float(string='Subtotal', help='Total payment')
+ inpatient_id = fields.Many2one('hospital.inpatient',
+ string='Inpatient',
+ help='Inpatient related to the payment')
+ date = fields.Datetime(string='Date', help="Date of payment")
+ tax_ids = fields.Many2many('account.tax', string='Tax',
+ help='Tax for the test')
diff --git a/base_hospital_management/models/inpatient_surgery.py b/base_hospital_management/models/inpatient_surgery.py
new file mode 100755
index 000000000..f1d5d951d
--- /dev/null
+++ b/base_hospital_management/models/inpatient_surgery.py
@@ -0,0 +1,92 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 InpatientSurgery(models.Model):
+ """Class holding Surgery details"""
+ _name = 'inpatient.surgery'
+ _inherit = ["mail.thread", "mail.activity.mixin"]
+ _description = 'Inpatient Surgery'
+
+ date = fields.Date(dafault=fields.date.today(), string='Date',
+ help='Date of adding surgery')
+ planned_date = fields.Datetime(string='Planned Date',
+ help='Planned date for surgery',
+ required=True)
+ name = fields.Char(string='Name', help='Name of the surgery',
+ required=True)
+ doctor_id = fields.Many2one('hr.employee',
+ string="Operating Doctor",
+ domain=[('job_id.name', '=', 'Doctor')],
+ help='Doctor responsible for the surgery',
+ required=True)
+ inpatient_id = fields.Many2one('hospital.inpatient',
+ string='Inpatient',
+ help='Inpatient to whom surgery is added')
+ hours_to_take = fields.Float(string='Duration',
+ help='Time duration for the surgery')
+ company_id = fields.Many2one('res.company', string='Company',
+ default=lambda self: self.env.company.id)
+ state = fields.Selection([('draft', 'Draft'), ('confirmed', 'Confirmed'),
+ ('done', 'Done'), ('cancel', 'Cancel'),
+ ], default='draft',
+ string='State', help='State of the slot')
+
+ def action_confirm(self):
+ """Function for confirming a surgery"""
+ self.sudo().write({
+ 'state': 'confirmed'
+ })
+
+ def action_cancel(self):
+ """Function for cancelling a surgery"""
+ self.sudo().write({
+ 'state': 'cancel'
+ })
+
+ def action_done(self):
+ """Function for change the state to surgery"""
+ self.sudo().write({
+ 'state': 'done'
+ })
+
+ @api.model
+ def get_doctor_slot(self):
+ """Function for returning surgery details to doctor's dashboard"""
+ data_list = []
+ state = {'confirmed': 'Confirmed',
+ 'cancel': 'Cancel',
+ 'done': 'Done',
+ 'draft': 'Draft'}
+ for rec in self.sudo().search(
+ [('doctor_id.user_id', '=', self.env.user.id)]):
+ data_list.append({
+ 'id': rec.id,
+ 'planned_date': rec.planned_date,
+ 'patient_id': rec.inpatient_id.patient_id.name,
+ 'surgery_name': rec.name,
+ 'state': state[rec.state]
+ })
+ return {
+ 'record': data_list
+ }
diff --git a/base_hospital_management/models/ir_attachment.py b/base_hospital_management/models/ir_attachment.py
new file mode 100755
index 000000000..a0f886f69
--- /dev/null
+++ b/base_hospital_management/models/ir_attachment.py
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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, models
+
+
+class IrAttachment(models.Model):
+ """Inherited for making the attachments public"""
+ _inherit = 'ir.attachment'
+
+ @api.model
+ def create(self, vals):
+ """Inherited to make the attachments public"""
+ vals['public'] = True
+ return super().create(vals)
diff --git a/base_hospital_management/models/lab_medicine_line.py b/base_hospital_management/models/lab_medicine_line.py
new file mode 100755
index 000000000..2b341942b
--- /dev/null
+++ b/base_hospital_management/models/lab_medicine_line.py
@@ -0,0 +1,54 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 LabMedicineLine(models.Model):
+ """Class holding Lab medicines"""
+ _name = 'lab.medicine.line'
+ _description = 'Lab Medicine Line'
+
+ lab_test_id = fields.Many2one('patient.lab.test',
+ string='Lab Test Line',
+ help='Lab test corresponds to the medicine')
+ test_id = fields.Many2one('lab.test', string='Test',
+ help='Test corresponds to medicine')
+ medicine_id = fields.Many2one('product.template',
+ domain="['|', ('medicine_ok', '=', True),"
+ "('vaccine_ok', '=', True)"
+ "]", required=True, string='Medicine',
+ help='Medicine for the lab test')
+ quantity = fields.Integer(string='Quantity', default=1,
+ help='Quantity of medicine')
+ qty_available = fields.Float(string='Available', help='Available quantity',
+ related='medicine_id.qty_available')
+ price = fields.Float(string='Price', help='Price for the medicine',
+ related='medicine_id.list_price')
+ sub_total = fields.Float(string='Subtotal',
+ help='Total cost of the medicine',
+ compute='_compute_sub_total')
+
+ @api.depends('quantity', 'price')
+ def _compute_sub_total(self):
+ """Method for computing total amount"""
+ for rec in self:
+ rec.sub_total = rec.price * rec.quantity
diff --git a/base_hospital_management/models/lab_test.py b/base_hospital_management/models/lab_test.py
new file mode 100755
index 000000000..7ae8081d1
--- /dev/null
+++ b/base_hospital_management/models/lab_test.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 LabTest(models.Model):
+ """Class holding lab test details"""
+ _name = 'lab.test'
+ _description = 'Laboratory Test'
+
+ name = fields.Char(string='Test', help='Name of the test')
+ patient_lead = fields.Float(string='Result Within',
+ help='Time taken to get the result')
+ price = fields.Monetary(string='Price', help="The cost for the test")
+ currency_id = fields.Many2one('res.currency', string='Currency',
+ default=lambda self:
+ self.env.user.company_id.currency_id.id,
+ required=True, help='Currency in which '
+ 'payments will be done')
+ tax_ids = fields.Many2many('account.tax', string='Tax',
+ help='Tax for the test')
+ medicine_ids = fields.One2many('lab.medicine.line',
+ 'test_id',
+ string='Medicines',
+ help='Medicines used for the test')
+ test_type = fields.Selection(
+ [('range', 'Range'), ('objective', 'Objective')],
+ string='Type', required=True, help='Type of test')
diff --git a/base_hospital_management/models/lab_test_line.py b/base_hospital_management/models/lab_test_line.py
new file mode 100755
index 000000000..4567fd3f7
--- /dev/null
+++ b/base_hospital_management/models/lab_test_line.py
@@ -0,0 +1,131 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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, _
+from odoo.exceptions import UserError
+
+
+class LabTestLine(models.Model):
+ """Class holing lab test line details"""
+ _name = "lab.test.line"
+ _description = "Lab Test Line"
+
+ name = fields.Char(string='Test Sequence', required=True,
+ copy=False, readonly=True, index=True,
+ default=lambda self: 'New', help='Name of lab test line')
+ patient_id = fields.Many2one('res.partner', string='Patient',
+ help='Choose the patient',
+ domain=[('patient_seq', 'not in',
+ ['New', 'Employee', 'User'])])
+ doctor_id = fields.Many2one('hr.employee', string='Doctor',
+ help='Choose the doctor',
+ domain=[('job_id.name', '=', 'Doctor')])
+ date = fields.Date(default=fields.Date.today(), string='Date',
+ help='Date of test')
+ test_ids = fields.Many2many('lab.test', string='Test',
+ help='All the tests')
+ patient_type = fields.Selection(selection=[
+ ('inpatient', 'Inpatient'), ('outpatient', 'Outpatient')
+ ], required=1, string='Patient Type', help='Choose the patient type')
+ op_id = fields.Many2one('hospital.outpatient', string='OP Number',
+ help='ID of outpatient')
+ ip_id = fields.Many2one('hospital.inpatient', string='Inpatient ID',
+ help='ID of inpatient')
+ state = fields.Selection(selection=[
+ ('draft', 'Draft'), ('created', 'created')
+ ], default='draft', string='State', help='State of the record')
+
+ @api.model
+ def create(self, vals):
+ """Sequence generation"""
+ if vals.get('name', 'New') == 'New':
+ vals['name'] = self.env['ir.sequence'].next_by_code(
+ 'lab_tests.draft.sequence') or 'New'
+ return super().create(vals)
+
+ def action_confirm(self):
+ """Method for confirming the test"""
+ if not self.test_ids:
+ raise UserError(_('You need to add a test before posting.'))
+ self.state = 'created'
+ self.env['patient.lab.test'].sudo().create({
+ 'patient_id': self.patient_id.id,
+ 'test_id': self.id,
+ 'patient_type': self.patient_type,
+ 'state': 'draft',
+ 'test_ids': self.test_ids.ids,
+ })
+
+ @api.model
+ def action_get_patient_data(self, rec_id):
+ """Method for fetching patient data"""
+ data = self.env['lab.test.line'].sudo().browse(rec_id)
+ if data:
+ patient_data = {
+ 'id': rec_id,
+ 'name': data.patient_id.name,
+ 'unique': data.patient_id.patient_seq,
+ 'email': data.patient_id.email,
+ 'phone': data.patient_id.phone,
+ 'dob': data.patient_id.date_of_birth,
+ 'image_1920': data.patient_id.image_1920,
+ 'gender': data.patient_id.gender,
+ 'status': data.patient_id.marital_status,
+ 'doctor': data.doctor_id.name,
+ 'patient_type': data.patient_type.capitalize(),
+ 'ticket': data.op_id.op_reference
+ if data.patient_type == 'outpatient' else data.ip_id.name,
+ 'test_data': []
+ }
+ if data.patient_id.blood_group:
+ blood_caps = data.patient_id.blood_group.capitalize()
+ patient_data['blood_group'] = blood_caps + str(
+ data.patient_id.rh_type),
+ for test in data.test_ids:
+ hours = int(test.patient_lead)
+ minutes = int((test.patient_lead - hours) * 60)
+ patient_data['test_data'].append({
+ 'id': test.id,
+ 'name': test.name,
+ 'patient_lead': "{:02d}:{:02d}".format(hours, minutes),
+ 'price': test.price,
+ })
+ return patient_data
+
+ @api.model
+ def create_lab_tests(self, data):
+ """Method for creating lab tests"""
+ test_ids = []
+ test = self.env['lab.test.line'].sudo().browse(data['id'])
+ test.state = 'created'
+ if data:
+ for rec in data['test_data']:
+ test_ids.append(rec['id'])
+ self.env['patient.lab.test'].sudo().create({
+ 'patient_id': test.patient_id.id,
+ 'test_id': data['id'],
+ 'patient_type': data['patient_type'].lower(),
+ 'state': 'draft',
+ 'test_ids': test_ids,
+ })
+ return {
+ 'message': 'success',
+ }
diff --git a/base_hospital_management/models/lab_test_result.py b/base_hospital_management/models/lab_test_result.py
new file mode 100755
index 000000000..f1abcc361
--- /dev/null
+++ b/base_hospital_management/models/lab_test_result.py
@@ -0,0 +1,91 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 LabTestResult(models.Model):
+ """Class holding lab test result"""
+ _name = 'lab.test.result'
+ _description = 'Lab Test Result'
+ _rec_name = 'test_id'
+
+ patient_id = fields.Many2one('res.partner', string='Patient',
+ domain=[('patient_seq', 'not in',
+ ['New', 'Employee', 'User'])],
+ help='Patient for whom the test has been done')
+ result = fields.Char(string='Result', help='Result of the test')
+ normal = fields.Char(string='Normal', help="The normal rate of the test")
+ uom_id = fields.Many2one('uom.uom', string='Unit',
+ help='Unit of the normal and result value')
+ parent_id = fields.Many2one('patient.lab.test', string='Tests',
+ help='The tests for which the result'
+ ' corresponds to')
+ test_id = fields.Many2one('lab.test', string="Test Name",
+ help='Name of the test')
+ attachment = fields.Binary(string='Result', help='Result document')
+ currency_id = fields.Many2one('res.currency',
+ related='test_id.currency_id',
+ string='Currency',
+ help='Currency in which payments to be done')
+ price = fields.Monetary(string='Cost', help='Cost for the test',
+ related='test_id.price')
+ tax_ids = fields.Many2many('account.tax', string='Tax',
+ help='Tax for the test')
+ state = fields.Selection(selection=[('processing', 'Processing'),
+ ('published', 'Published')],
+ string='State', help='State of the result',
+ default='processing', compute='_compute_state')
+
+ @api.depends('attachment')
+ def _compute_state(self):
+ """Method for computing the state of result based on attachment"""
+ for rec in self:
+ if rec.attachment:
+ rec.state = 'published'
+ else:
+ rec.state = 'processing'
+
+ @api.model
+ def print_test_results(self, **kwargs):
+ """Method for printing rest result"""
+ data = self.sudo().search(kwargs['domain'])
+ context = []
+ for rec in data:
+ self.env.cr.execute(
+ f"""SELECT id FROM ir_attachment WHERE res_id = {rec.id}
+ and res_model='lab.test.result' """)
+ attachment_id = False
+ attachment = self.env.cr.dictfetchall()
+ if attachment:
+ attachment_id = attachment[0]['id']
+ context.append({
+ 'id': rec.id,
+ 'parent_id': rec.parent_id.test_id.name,
+ 'patient_id': [rec.parent_id.patient_id.id,
+ rec.parent_id.patient_id.name],
+ 'test_id': rec.test_id.name,
+ 'attachment_id': attachment_id,
+ 'normal': rec.normal,
+ 'result': rec.result,
+ 'unit': rec.uom_id.name if rec.uom_id else ''
+ })
+ return context
diff --git a/base_hospital_management/models/medicine_brand.py b/base_hospital_management/models/medicine_brand.py
new file mode 100755
index 000000000..23a4d09eb
--- /dev/null
+++ b/base_hospital_management/models/medicine_brand.py
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 MedicineBrand(models.Model):
+ """Model holding all medicine brands"""
+ _name = 'medicine.brand'
+ _description = 'Medicine Brand'
+
+ name = fields.Char(string="Brand", help='Name of the brand')
+ medicine_ids = fields.One2many('product.template',
+ 'medicine_brand_id',
+ string='Medicine',
+ help='All medicines belongs to this brand')
diff --git a/base_hospital_management/models/nursing_plan.py b/base_hospital_management/models/nursing_plan.py
new file mode 100755
index 000000000..157fc302a
--- /dev/null
+++ b/base_hospital_management/models/nursing_plan.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 NursingPlan(models.Model):
+ """Class holding nursing plan"""
+ _name = 'nursing.plan'
+ _description = "Nursing Plan"
+
+ admission_id = fields.Many2one('hospital.inpatient',
+ string='Patient',
+ help='Name of the inpatient')
+ date = fields.Datetime(string='Visit Time', help='Date and time of visit')
+ status = fields.Char(string='Status',
+ help='Physical condition of the patient')
+ notes = fields.Text(string='Note', help='You can add the notes here')
diff --git a/base_hospital_management/models/patient_booking.py b/base_hospital_management/models/patient_booking.py
new file mode 100755
index 000000000..dbc60788c
--- /dev/null
+++ b/base_hospital_management/models/patient_booking.py
@@ -0,0 +1,97 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 PatientBooking(models.Model):
+ """Class holding patient booking"""
+ _name = 'patient.booking'
+ _inherit = 'mail.thread'
+ _description = 'Patient Booking'
+ _rec_name = 'patient_id'
+
+ booking_reference = fields.Char(string="OP Number",
+ help='Reference number indicating '
+ 'the booking', readonly=True,
+ default='New')
+ patient_id = fields.Many2one('res.partner', string='Patient',
+ domain=[('patient_seq', 'not in',
+ ['New', 'Employee', 'User'])],
+ help='Choose the patient for booking',
+ required=True)
+ doctor_id = fields.Many2one('doctor.allocation',
+ string='Doctor',
+ help='Select the doctor',
+ required=True,
+ domain=[('slot_remaining', '>', 0),
+ ('date', '=', fields.date.today()),
+ ('state', '=', 'confirm')])
+ currency_id = fields.Many2one('res.currency',
+ string='Currency',
+ help='Currency in which consultation fee '
+ 'is calculating',
+ default=lambda self: self.env.user.company_id
+ .currency_id.id,
+ required=True)
+ consultation_fee = fields.Monetary(
+ related='doctor_id.doctor_id.consultancy_charge', string="Fee",
+ help='Consultation fee',
+ readonly=True)
+ booking_date = fields.Date(string="Booking Date", help='Date of booking',
+ default=fields.Date.today())
+ reason = fields.Text(string='Reason', help='Reason for booking')
+ state = fields.Selection(
+ [('draft', 'Draft'), ('confirm', 'Confirmed'),
+ ('cancel', 'Cancelled')],
+ default='draft', string='State', help='State of patient booking')
+ company_id = fields.Many2one('res.company', string='Company',
+ default=lambda self: self.env.company.id)
+ slot = fields.Float(string='Slot', help='Slot for the patient',
+ copy=False)
+
+ @api.model
+ def create(self, vals):
+ """Method for creating booking reference"""
+ if vals.get('booking_reference', 'New') == 'New':
+ vals['booking_reference'] = self.env['ir.sequence'].next_by_code(
+ 'patient.booking') or 'New'
+ return super().create(vals)
+
+ @api.onchange('booking_date')
+ def _onchange_booking_date(self):
+ """Method for adding domain for doctor_id"""
+ return {'domain': {'doctor_id': [('slot_remaining', '>', 0),
+ ('date', '=', self.booking_date),
+ ('state', '=', 'confirm')]}}
+
+ def action_confirm_booking(self):
+ """Confirmation of booking"""
+ if self.doctor_id.latest_slot == 0:
+ self.slot = self.doctor_id.work_from
+ else:
+ self.slot = self.doctor_id.latest_slot + self.doctor_id.time_avg
+ self.doctor_id.latest_slot = self.slot
+ self.state = 'confirm'
+
+ def action_booking_cancel(self):
+ """Method for cancelling a booking"""
+ self.state = 'cancel'
diff --git a/base_hospital_management/models/patient_lab_test.py b/base_hospital_management/models/patient_lab_test.py
new file mode 100755
index 000000000..72e061726
--- /dev/null
+++ b/base_hospital_management/models/patient_lab_test.py
@@ -0,0 +1,308 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 PatientLabTest(models.Model):
+ """Class holding Patient lab test details"""
+ _name = 'patient.lab.test'
+ _description = 'Patient Lab Test'
+ _rec_name = 'test_id'
+
+ test_id = fields.Many2one('lab.test.line', string='Test',
+ help='Name of the test')
+ patient_id = fields.Many2one('res.partner', string="Patient",
+ domain=[('patient_seq', 'not in',
+ ['New', 'Employee', 'User'])],
+ required=True, help='Choose the patient')
+ patient_type = fields.Selection(selection=[
+ ('inpatient', 'Inpatient'), ('outpatient', 'Outpatient')
+ ], related='test_id.patient_type', string='Type',
+ help='Choose the type of patient')
+ test_ids = fields.Many2many('lab.test',
+ related='test_id.test_ids', string='Tests',
+ help='All the tests added for the patient')
+ date = fields.Date(string='Date', help='Date of test',
+ default=fields.date.today())
+ total_price = fields.Float(string='Price', help='Total price for the test')
+ currency_id = fields.Many2one('res.currency', string='Currency',
+ help='Currency in which lab test amount will'
+ ' be calculated',
+ default=lambda self: self.env.user.company_id
+ .currency_id.id,
+ required=True)
+ state = fields.Selection([('draft', 'Draft'),
+ ('test', 'Test In Progress'),
+ ('completed', 'Completed')],
+ string='State', readonly=True,
+ help='State of test',
+ default="draft")
+ result_ids = fields.One2many('lab.test.result',
+ 'parent_id',
+ string="Result", help='Results of the test')
+ medicine_ids = fields.One2many('lab.medicine.line',
+ 'lab_test_id',
+ string='Medicine',
+ compute='_compute_medicine_ids',
+ readonly=False,
+ help='Medicines needed for the test')
+ notes = fields.Text(string='Notes', help='Notes regarding the test')
+ lab_id = fields.Many2one('hospital.laboratory', string='Lab',
+ help='Lab in which test is doing')
+ invoice_id = fields.Many2one('account.move', string='Invoice',
+ help='Invoice for the test', copy=False)
+ order = fields.Integer(string='Sale Order',
+ help='Number of sale orders for vaccines and '
+ 'medicines',
+ copy=False)
+ started = fields.Boolean(string='Test Started',
+ help='True if the test has been started',
+ copy=False)
+ invoiced = fields.Boolean(string='Invoiced',
+ help='True if the test has been invoiced',
+ copy=False)
+ sold = fields.Boolean(string='Sold',
+ help='If true, sale order smart button will be '
+ 'visible ', copy=False)
+ company_id = fields.Many2one('res.company', string='Company',
+ default=lambda self: self.env.company.id)
+ invoice_count = fields.Integer(string='Invoice '
+ 'Count',
+ compute='_compute_invoice_count',
+ help='Total number of invoices for this '
+ 'patient lab test.')
+ sale_count = fields.Integer(string='Sale '
+ 'Count',
+ compute='_compute_sale_count',
+ help='Total number of sale orders for this '
+ 'patient lab test.')
+ inpatient_id = fields.Many2one('hospital.inpatient',
+ string='Inpatient',
+ help='Choose the inpatient')
+
+ @api.depends('test_id')
+ def _compute_medicine_ids(self):
+ """Method for computing medicine_ids"""
+ for record in self:
+ record.medicine_ids = self.test_ids.medicine_ids
+
+ def _compute_invoice_count(self):
+ """Method for computing invoice_count"""
+ for record in self:
+ record.invoice_count = self.env['account.move'].sudo().search_count(
+ ['|', (
+ 'ref', '=', record.test_id.name), ('payment_reference', '=',
+ record.test_id.name)])
+
+ def _compute_sale_count(self):
+ """Method for computing sale_count"""
+ for record in self:
+ record.sale_count = self.env['sale.order'].sudo().search_count([(
+ 'reference', '=', record.test_id.name)])
+
+ @api.model
+ def action_get_patient_data(self, rec_id):
+ """Returns data to the lab dashboard"""
+ data = self.sudo().browse(rec_id)
+ if data:
+ patient_data = {
+ 'id': rec_id,
+ 'sequence': data.test_id.name,
+ 'name': data.patient_id.name,
+ 'unique': data.patient_id.patient_seq,
+ 'email': data.patient_id.email,
+ 'phone': data.patient_id.phone,
+ 'dob': data.patient_id.date_of_birth,
+ 'image_1920': data.patient_id.image_1920,
+ 'gender': data.patient_id.gender,
+ 'status': data.patient_id.marital_status,
+ 'doctor': data.test_id.doctor_id.name,
+ 'patient_type': data.patient_type.capitalize(),
+ 'state': data.state,
+ 'invoiced': data.invoiced,
+ 'ticket': data.test_id.op_id.op_reference
+ if data.patient_type == 'outpatient'
+ else data.test_id.patient_id.patient_seq,
+ 'test_data': [],
+ 'medicine': [],
+ 'result_ids': [],
+ }
+ if data.patient_id.blood_group:
+ blood_caps = data.patient_id.blood_group.capitalize()
+ patient_data['blood_group'] = blood_caps + str(
+ data.patient_id.rh_type),
+ for test in data.test_ids:
+ patient_data['test_data'].append({
+ 'id': test.id,
+ 'name': test.name,
+ 'patient_lead': test.patient_lead,
+ 'price': test.price,
+ })
+ for medicine in data.medicine_ids:
+ patient_data['medicine'].append({
+ 'id': medicine.medicine_id.id,
+ 'name': medicine.medicine_id.name,
+ 'quantity': medicine.quantity
+ })
+ for result in data.result_ids:
+ patient_data['result_ids'].append({
+ 'id': result.id,
+ 'name': result.test_id.name,
+ 'result': result.result,
+ 'normal': result.normal,
+ 'uom_id': result.uom_id.name,
+ 'attachment': result.attachment,
+ 'cost': result.price,
+ 'state': result.state
+ })
+ return patient_data
+
+ @api.model
+ def start_test(self, rec_id):
+ """Method for creating lab tests from lab dashboard"""
+ data = self.sudo().browse(rec_id)
+ data.state = 'test'
+ data.started = True
+ med_list = data.medicine_ids.ids
+ for rec in data.test_ids:
+ medicine_ids = [item for item in rec.medicine_ids.ids]
+ data.sudo().write({
+ 'result_ids': [(0, 0, {
+ 'patient_id': data.patient_id.id,
+ 'test_id': rec.id,
+ 'tax_ids': rec.tax_ids.ids
+ })]
+ })
+ [med_list.append(i) for i in medicine_ids]
+ data.medicine_ids = med_list
+
+ @api.model
+ def test_end(self, rec_id):
+ """Method for ending test from lab dashboard"""
+ data = self.sudo().browse(rec_id)
+ data.state = 'completed'
+
+ @api.model
+ def create_invoice(self, rec_id):
+ """Method for creating invoice"""
+ data = self.sudo().browse(rec_id)
+ order_lines = []
+ partner_id = data.patient_id.id
+ if data.medicine_ids:
+ for rec in data.medicine_ids:
+ order_lines.append((0, 0, {
+ 'product_id': self.env['product.product'].sudo().search([
+ ('product_tmpl_id', '=', rec.medicine_id.id)]).id,
+ 'name': rec.medicine_id.name,
+ 'price_unit': rec.price,
+ 'product_uom_qty': rec.quantity,
+ }))
+ sale_order = self.env['sale.order'].sudo().create({
+ 'partner_id': partner_id,
+ 'date_order': fields.Date.today(),
+ 'reference': data.test_id.name,
+ 'order_line': order_lines
+ })
+ data.sold = True
+ data.order = sale_order.id
+ invoice_id = self.env['account.move'].sudo().search(
+ [('ref', '=', data.test_id.name)
+ ], limit=1)
+ if not invoice_id:
+ invoice_id = self.env['account.move'].sudo().create({
+ 'move_type': 'out_invoice',
+ 'partner_id': partner_id,
+ 'invoice_date': fields.Date.today(),
+ 'date': fields.Date.today(),
+ 'ref': data.test_id.name
+ })
+ for rec in data.result_ids:
+ invoice_id.sudo().write({
+ 'invoice_line_ids': [(
+ 0, 0, {
+ 'quantity': 1,
+ 'name': rec.test_id.name,
+ 'price_unit': rec.price,
+ 'tax_ids': rec.tax_ids.ids,
+ 'price_subtotal': rec.price,
+ }
+ )]
+ })
+ data.invoiced = True
+ data.invoice_id = invoice_id.id
+
+ def action_test_end(self):
+ """Button action for test end"""
+ self.state = 'completed'
+
+ def action_start_test(self):
+ """Button action for start test"""
+ self.start_test(self.id)
+
+ def action_create_invoice(self):
+ """Button action for creating invoice"""
+ self.create_invoice(self.id)
+
+ def action_view_invoice(self):
+ """Method for viewing invoice from the smart button"""
+ return {
+ 'name': 'Invoice',
+ 'type': 'ir.actions.act_window',
+ 'res_model': 'account.move',
+ 'view_mode': 'tree,form',
+ "context": {"create": False, 'default_move_type': 'out_invoice'},
+ 'domain': ['|', (
+ 'ref', '=', self.name), ('payment_reference', '=', self.name)]
+ }
+
+ def action_view_sale_order(self):
+ """Method for viewing sale order from the smart button"""
+ return {
+ 'name': 'Sale order',
+ 'res_model': 'sale.order',
+ 'view_mode': 'form',
+ 'type': 'ir.actions.act_window',
+ 'res_id': self.env['sale.order'].sudo().search([('reference', '=',
+ self.name)])[0].id
+ }
+
+ def print_lab_tests(self):
+ """Method for printing the lab test result"""
+ test_list = []
+ for rec in self.result_ids:
+ datas = {
+ 'test': rec.test_id.test,
+ 'normal': rec.normal,
+ 'uom_id': rec.uom_id.name,
+ 'result': rec.result,
+ 'cost': rec.price,
+ 'currency': self.env.company.currency_id.symbol
+ }
+ test_list.append(datas)
+ data = {
+ 'datas': test_list,
+ 'date': self.date,
+ 'patient_name': self.patient_id.name,
+ 'doctor_name': self.test_id.doctor_id.name
+ }
+ return self.env.ref(
+ 'base_hospital_management.action_report_patient_lab_tests').report_action(self, data=data)
diff --git a/base_hospital_management/models/patient_room.py b/base_hospital_management/models/patient_room.py
new file mode 100755
index 000000000..287b344f6
--- /dev/null
+++ b/base_hospital_management/models/patient_room.py
@@ -0,0 +1,67 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 PatientRoom(models.Model):
+ """Class holding Patient room details"""
+ _name = 'patient.room'
+ _description = 'Patient Room'
+
+ name = fields.Char(string="Name", help='The name of room', required=True)
+ currency_id = fields.Many2one('res.currency', string='Currency',
+ default=lambda self: self.env.user.company_id
+ .currency_id.id,
+ required=True, help='Currency in which '
+ 'payments will be done')
+ building_id = fields.Many2one('hospital.building',
+ string="Block Name",
+ required="True", help='Building to which '
+ 'the room corresponds '
+ 'to')
+ nurse_ids = fields.Many2many('hr.employee', string='Nurses',
+ domain="[('job_id.name','=','Nurse')]",
+ help='Nurses of the room')
+ bed_type = fields.Selection([('gatch', 'Gatch Bed'),
+ ('electric', 'Electric'),
+ ('stretcher', 'Stretcher'),
+ ('low', 'Low Bed'),
+ ('air', 'Low Air Loss'),
+ ('circo', 'Circo Electric'),
+ ('clinitron', 'Clinitron'),
+ ], string="Bed Type", help='Select the type '
+ 'of bed')
+ rent = fields.Monetary(string='Rent', help='Rent for the room')
+ state = fields.Selection([('avail', 'Available'),
+ ('reserve', 'Reserve'),
+ ('not', 'Unavailable'), ],
+ string='State', readonly=True,
+ default="avail", help='State of room')
+ room_facilities_ids = fields.Many2many('room.facility',
+ string='Facilities',
+ help='Facilities of room')
+ floor_no = fields.Integer(string="Floor No.", help='The floor to '
+ 'which the room '
+ 'corresponds to')
+
+ _sql_constraints = [('unique_room', 'unique (name)',
+ 'Room number should be unique!')]
diff --git a/base_hospital_management/models/pharmacy_medicine.py b/base_hospital_management/models/pharmacy_medicine.py
new file mode 100755
index 000000000..dcbc90b7f
--- /dev/null
+++ b/base_hospital_management/models/pharmacy_medicine.py
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 PharmacyMedicine(models.Model):
+ """Class holding Pharmacy medicine details"""
+ _name = 'pharmacy.medicine'
+ _description = 'pharmacy Medicine'
+ _rec_name = 'product_id'
+
+ product_id = fields.Many2one('product.template',
+ string='Medicine',
+ help='Name of medicine',
+ domain="[('medicine_ok', '=', True)]")
+ pharmacy_id = fields.Many2one('hospital.pharmacy',
+ string='Pharmacy',
+ help='Name of pharmacy')
+ qty_available = fields.Float(related='product_id.qty_available',
+ string='Available Quantity',
+ help='The quantity of product available')
+ list_price = fields.Float(related='product_id.list_price', string='Price',
+ help='Price of the medicine')
diff --git a/base_hospital_management/models/prescription_line.py b/base_hospital_management/models/prescription_line.py
new file mode 100755
index 000000000..a00633ac5
--- /dev/null
+++ b/base_hospital_management/models/prescription_line.py
@@ -0,0 +1,65 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 PrescriptionLine(models.Model):
+ """Class holding prescription line details"""
+ _name = 'prescription.line'
+ _description = 'Prescription Lines'
+ _rec_name = 'prescription_id'
+
+ prescription_id = fields.Many2one('hospital.prescription',
+ string='Prescription',
+ help='Name of the prescription')
+ medicine_id = fields.Many2one('product.template', domain=[
+ '|', ('medicine_ok', '=', True), ('vaccine_ok', '=', True)],
+ string='Medicine', required=True,
+ help='Medicines or vaccines')
+ quantity = fields.Integer(string='Quantity', required=True,
+ help="The number of medicines for the time "
+ "period")
+ no_intakes = fields.Float(string='Intakes', required=True,
+ help="How much medicine want to take")
+ time = fields.Selection(
+ [('once', 'Once in a day'), ('twice', 'Twice in a Day'),
+ ('thrice', 'Thrice in a day'), ('morning', 'In Morning'),
+ ('noon', 'In Noon'), ('evening', 'In Evening')], string='Time',
+ required=True,
+ help='The interval for medicine intake')
+ note = fields.Selection(
+ [('before', 'Before Food'), ('after', 'After Food')],
+ string='Before/ After Food',
+ help='Whether the medicine to be taken before or after food')
+ inpatient_id = fields.Many2one('hospital.inpatient',
+ string='Inpatient',
+ help='The inpatient corresponds to the '
+ 'prescription line')
+ outpatient_id = fields.Many2one('hospital.outpatient',
+ string='Outpatient',
+ help='The outpatient corresponds to the '
+ 'prescription line')
+ res_partner_id = fields.Many2one('res.partner',
+ string='Patient',
+ help='The outpatient corresponds to the '
+ 'prescription line',
+ related='outpatient_id.patient_id')
diff --git a/base_hospital_management/models/product_template.py b/base_hospital_management/models/product_template.py
new file mode 100755
index 000000000..5cef9e0e2
--- /dev/null
+++ b/base_hospital_management/models/product_template.py
@@ -0,0 +1,63 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 ProductTemplate(models.Model):
+ """Inherited to add more fields and functions"""
+ _inherit = 'product.template'
+
+ medicine_ok = fields.Boolean(string='Medicine', help='True for medicines')
+ vaccine_ok = fields.Boolean(string="Vaccine", help='True for vaccines')
+ pharmacy_id = fields.Many2one('hospital.pharmacy',
+ string='Pharmacy',
+ help='Name of the pharmacy')
+ medicine_brand_id = fields.Many2one('medicine.brand',
+ string='Brand',
+ help='Indicates the brand of medicine '
+ 'or vaccine')
+
+ @api.model
+ def action_get_medicine_data(self):
+ """Returns medicine list to the pharmacy dashboard"""
+ medicines = []
+ for rec in self.env['product.template'].sudo().search(
+ [('medicine_ok', '=', True)]):
+ medicines.append(
+ [rec.name, rec.list_price, rec.qty_available, rec.image_1920])
+ values = {
+ 'medicine': medicines,
+ }
+ return values
+
+ @api.model
+ def action_get_vaccine_data(self):
+ """Returns vaccine list to the pharmacy dashboard"""
+ vaccines = []
+ for rec in self.env['product.template'].sudo().search(
+ [('vaccine_ok', '=', True)]):
+ vaccines.append(
+ [rec.name, rec.list_price, rec.qty_available, rec.image_1920])
+ values = {
+ 'medicine': vaccines,
+ }
+ return values
diff --git a/base_hospital_management/models/res_partner.py b/base_hospital_management/models/res_partner.py
new file mode 100755
index 000000000..870f696c8
--- /dev/null
+++ b/base_hospital_management/models/res_partner.py
@@ -0,0 +1,584 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 math
+import re
+import base64
+from datetime import date
+from barcode import EAN13
+from barcode.writer import ImageWriter
+from dateutil.relativedelta import *
+from odoo import api, fields, models
+
+
+class ResPartner(models.Model):
+ """Inherited to add more fields and functions"""
+ _inherit = 'res.partner'
+ _description = 'Hospital Patients'
+
+ date_of_birth = fields.Date(string='Date of Birth',
+ help='Date of birth of the patient')
+ blood_group = fields.Selection(string='Blood Group',
+ help='Blood group of the patient',
+ selection=[('a', 'A'), ('b', 'B'),
+ ('o', 'O'), ('ab', 'AB')])
+ rh_type = fields.Selection(selection=[('-', '-ve'), ('+', '+ve')],
+ string='RH Type',
+ help='Rh type of the blood group')
+ gender = fields.Selection(selection=[
+ ('male', 'Male'), ('female', 'Female'), ('other', 'Other')
+ ], string='Gender', help='Gender of the patient')
+ marital_status = fields.Selection(selection=[
+ ('married', 'Married'), ('unmarried', 'Unmarried'), ('widow', 'Widow'),
+ ('widower', 'Widower'), ('divorcee', 'Divorcee')
+ ], string='Marital Status', help='Marital status of patient')
+ is_alive = fields.Selection(
+ string='Status',
+ selection=[('alive', 'Alive'), ('dead', 'Dead')],
+ default='alive', help='True for alive patient')
+ patient_seq = fields.Char(string='Patient No.',
+ help='Sequence number of the patient', copy=False,
+ readonly=True, index=True,
+ default=lambda self: 'New')
+ notes = fields.Html(string='Note', help='Notes regarding the notes',
+ sanitize_style=True)
+ patient_profession = fields.Char(string="Profession",
+ help="Profession of patient")
+ doctor_id = fields.Many2one('hr.employee',
+ domain=[('job_id.name', '=', 'Doctor')],
+ string="Family Doctor",
+ help='Family doctor of the patient')
+ barcode = fields.Char(string='Barcode', help='Barcode for the patient')
+ barcode_png = fields.Binary(string='Barcode PNG',
+ help='Image file of the barcode', readonly=True)
+ group = fields.Selection(selection=[
+ ('hindu', 'Hindu'), ('muslim', 'Muslim'), ('christian', 'Christian')],
+ string="Ethnic Group", help="Specify your religion")
+ risk = fields.Text(string="Genetic Risks",
+ help='Genetic risks of the patient')
+ insurance_id = fields.Many2one('hospital.insurance',
+ string="Insurance",
+ help="Patient insurance")
+ unique_id = fields.Char(string='Unique ID',
+ help="Unique identifier to fetch "
+ "patient insurance data")
+ family_ids = fields.One2many('hospital.family',
+ 'family_id',
+ string="Family ID", help='Family of a patient')
+ lab_test_ids = fields.One2many('patient.lab.test',
+ 'patient_id',
+ string='Lab Test',
+ help='Lab tests for the patient')
+ prescription_ids = fields.One2many('prescription.line',
+ 'res_partner_id',
+ string='Prescription',
+ help='Prescription for patient')
+ economic_level = fields.Selection(selection=[
+ ('low', 'Lower Class'), ('middle', 'Middle Class'),
+ ('upper', 'Upper Class')], string="Socioeconomic",
+ help="Specify your economic status")
+ education_level = fields.Selection(selection=[
+ ('post', 'Post Graduation'), ('graduation', 'Graduation'),
+ ('pre', 'Pre Graduation')], string="Education Level",
+ help="Education status of patient")
+ house_level = fields.Selection(selection=[
+ ('good', 'Good'), ('bad', 'Bad'), ('poor', 'Poor')],
+ string="House Condition", help="Specify your house's condition")
+ work_home = fields.Boolean(string='Work At Home',
+ help='True if you are working from home')
+ hours_outside = fields.Integer(string='Hours Stay Outside Home',
+ help="Specify how many hours you stay away "
+ "from home")
+ hostile = fields.Boolean(string='Hostile Area',
+ help="Specify your house in a friendly "
+ "neighbourhood ")
+ income = fields.Monetary(string='Income', help="The in come of patient")
+ currency_id = fields.Many2one('res.currency', string='Currency',
+ help='Currency in which invoices and payments'
+ ' will be generated',
+ default=lambda self: self.env.user.company_id
+ .currency_id.id, required=True)
+ sanitary = fields.Boolean('Sanitary Sewers',
+ help="A sewer or sewer system for carrying off "
+ "wastewater, waste matter from a residence,"
+ " business, etc")
+ running = fields.Boolean(string='Running Water',
+ help="water that comes into a building through "
+ "pipes. A cabin with hot and cold running "
+ "water.")
+ electricity = fields.Boolean(string='Electricity',
+ help='True if you have electricity')
+ gas = fields.Boolean(string='Gas Supply',
+ help='True if you have gas supply')
+ trash = fields.Boolean(string='Trash Collection',
+ help='True if you have trash collection')
+ home_phone = fields.Boolean(string='Telephone',
+ help='True if you have telephone')
+ tv = fields.Boolean(string='Television', help='True if you have television')
+ internet = fields.Boolean(string='Internet',
+ help='True if you have internet')
+ help = fields.Selection([('yes', 'Yes'), ('no', 'No')],
+ string="Family Help",
+ help="Specify whether your family is willing "
+ "to help or not")
+ discussion = fields.Selection([('yes', 'Yes'), ('no', 'No')],
+ string="Family Discussion ",
+ help="Specify your family have a good "
+ "discussion at home ")
+ ability = fields.Selection([('very', 'Very good'), ('good', 'Good'),
+ ('bad', 'Bad'), ('poor', 'Poor')],
+ string="Family Ability",
+ help="family status of the patient")
+ time_sharing = fields.Selection([('yes', 'Yes'), ('no', 'No')],
+ string=" Family Time Sharing ",
+ help="Specify your family share time "
+ "at home ")
+ affection = fields.Selection([('very', 'Very good'),
+ ('good', 'Good'),
+ ('bad', 'Bad'), ('poor', 'Poor')],
+ string="Family Affection ",
+ help="Specify your family's affection ")
+ single = fields.Boolean(string='Single Parent Family',
+ help='Whether single parent family or not')
+ violence = fields.Boolean(string='Domestic Violence',
+ help='True if you are facing any domestic '
+ 'violence')
+ children = fields.Boolean(string='Working Children',
+ help='Do you have working children')
+ abuse = fields.Boolean(string='Sexual Abuse',
+ help='Do you faced any sexual abuse')
+ drug = fields.Boolean(string='Drug Addiction',
+ help='Do you have drug addiction')
+ withdrawal = fields.Boolean(string='Withdrawal',
+ help='Do you faced any withdrawal symptoms')
+ in_prison = fields.Boolean(string='Has Been In Prison',
+ help='True if you had been in prison')
+ current_prison = fields.Boolean(string='Currently In Prison',
+ help='True if you are in prison currently')
+ relative_prison = fields.Boolean(string='Relative In Prison',
+ help='True if any of your relative is '
+ 'in prison')
+ hospital_vaccination_ids = fields.One2many(
+ 'hospital.vaccination', 'patient_id',
+ string='Vaccination', help='Vaccination details of '
+ 'patient')
+ fertile = fields.Boolean(string='Fertile', help="""Capable of developing
+ into a complete organism;
+ fertilized. Capable of supporting
+ plant life; favorable to the
+ growth of crops and plants.""")
+ menarche_age = fields.Integer(string='Menarche Age', help="""The first
+ menstrual period in a female adolescent""")
+ pause = fields.Boolean(string='Menopause', help="""Menopause is a point in
+ time 12 months after a woman's last period""")
+ pause_age = fields.Integer(string='Menopause Age',
+ help='Age at which menopause occurred')
+ pap = fields.Boolean(string='PAP Test',
+ help="""
+ A procedure in which a small brush is used to gently
+ remove cells from the surface of the cervix and the
+ area around it so they can be checked under a
+ microscope for cervical cancer or cell changes that
+ may lead to cervical cancer.""")
+ colposcopy = fields.Boolean(string='Colposcopy', help=""" test to take a
+ closer look at your cervix""")
+ self = fields.Boolean(string='Self breast examination',
+ help="A breast self-exam for breast awareness is "
+ "in inspection "
+ "of your breasts that women do on your own")
+ mommography = fields.Boolean(string='Mommography',
+ help="Mammograms can be used to look for "
+ "breast cancer")
+ last_pap = fields.Date(string="Last PAP Test",
+ help='The date on which last PAP test has been done')
+ last_col = fields.Date(string="Last Colposcopy",
+ help='The date on which last colposcopy has been '
+ 'done')
+ deceased = fields.Boolean(string='Deceased during 1st week',
+ help='The family member deceased during first '
+ 'week')
+ grandiva = fields.Boolean(string='Grandiva', help='True for grandiva')
+ alive = fields.Boolean(string='Born Alive', help='Whether born alive or '
+ 'not')
+ premature = fields.Integer(string='Premature',
+ help="Premature birth is birth that happens too"
+ "soon, before 37 weeks of pregnancy")
+ abortions = fields.Integer(string='No Of Abortions', help='Number of '
+ 'abortions of '
+ 'patient')
+ exercise = fields.Boolean(string='Exercise', help='True if patient doing '
+ 'exercise regularly')
+ minute = fields.Integer(string='Minute/Day', help='The duration of '
+ 'exercise per day')
+
+ day_sleep = fields.Boolean(string='Sleeps At Daytime', help='True if '
+ 'sleeps at '
+ 'daytime')
+ sleep_hrs = fields.Integer(string='Sleep Hours', help='Duration of sleep')
+ meals = fields.Integer(string='Meals/Day', help='Number of meals per day')
+ alone = fields.Boolean(string='Eat Alone', help='True if eats alone')
+ coffee = fields.Boolean(string='Coffee', help='True if you have a habit '
+ 'of drinking coffee')
+ cup = fields.Integer(string='Cups/Day', help='Number of cups of coffee '
+ 'per day')
+ drink = fields.Boolean(string='Soft Drink', help='True if you drinks soft '
+ 'drinks')
+ salt = fields.Boolean(string='Salt', help='True if you use salt')
+ diet = fields.Boolean(string='Currently On Diet', help='True if you are '
+ 'on diet currently')
+ smoke = fields.Boolean(string='Smoker', help='True for smoker')
+ ex_smoke = fields.Boolean(string='Ex-Smoker', help='True for ex-smoker')
+ age_start = fields.Integer(string='Age of Started Smoking',
+ help='Age on which you started your smoking')
+ cigarettes = fields.Integer(string='Cigarettes/Day',
+ help='Number of cigarettes per day')
+ passive = fields.Boolean(string='Passive Smoker',
+ help='True for passive smokers')
+ age_quit = fields.Integer(string='Age of Quitting',
+ help='Age at which you quit your smoking habit')
+ alcoholic = fields.Boolean(string='Alcoholic', help='True for alcoholics')
+ ex_alcoholic = fields.Boolean(string='Ex-Alcoholic', help='True for ex- '
+ 'alcoholics')
+ age_start_alco = fields.Integer(string='Age to Start Drinking',
+ help='Age at which you started your '
+ 'drinking habit')
+ beer = fields.Integer(string='Beer/Day',
+ help='Number of beers per day')
+ liquor = fields.Integer(string='Liquor/Day',
+ help='Liquors per day')
+ wine = fields.Integer(string='Wine/Day',
+ help='Number of wines per day')
+ age_quit_alcoholic = fields.Integer(string='Age Of Quitting',
+ help='Age at which you started your '
+ 'drinking habit')
+ drugs = fields.Boolean(string='Drug User', help='True for drug users')
+ ex_drugs = fields.Boolean(string='Ex-Drug User', help='True for Ex drug '
+ 'user')
+ iv_user = fields.Boolean(string='IV Drug User', help='True for IV drug '
+ 'user')
+ age_start_drug = fields.Integer(string='Age to Start Using Drugs',
+ help='Age at which you started using drug')
+ age_quit_drug = fields.Integer(string='Drug Quitting Age', help='Age of '
+ 'quitting '
+ 'drug')
+ orientation = fields.Selection([('straight', 'Straight'),
+ ('homo', 'Homosexual'),
+ ('trans', 'Trans-Gender')],
+ string="Orientation")
+ age_sex = fields.Integer(string="Age of First Encounter",
+ help='Age of first sex encounter')
+ partners = fields.Integer(string="No of Partners",
+ help='Number of sex partners')
+ anti = fields.Selection(
+ [('pills', 'Contraceptive Pills'), ('ring', 'Contraceptive Ring'),
+ ('injection', 'Contraceptive Injection')],
+ string="Contraceptive Methods", help='Choose your contraceptive method')
+ oral = fields.Boolean(string='Oral Sex', help=("uttered by the mouth or in "
+ "words"))
+ anal = fields.Boolean(string='Anal Sex', help="True if you are "
+ "encountering anal sex")
+ prostitute = fields.Boolean(string='Prostitute', help='True for '
+ 'prostitutes')
+ prostitute_sex = fields.Boolean(string='Sex With Prostitute',
+ help='True if you are encountered sex '
+ 'with prostitute')
+ sex_notes = fields.Text(string='Notes', help='Write down the notes')
+ rider = fields.Boolean(string='Motorcycle Rider', help='True for '
+ 'motorcycle riders')
+ helmet = fields.Boolean(string='Uses Helmet',
+ help='True if you regularly use helmet')
+ laws = fields.Boolean(string='Obey Traffic Laws',
+ help='True if you obey traffic rules')
+ revision = fields.Boolean(string='Car Revision', help='True if car '
+ 'revision is done')
+ belt = fields.Boolean(string='Seat Belt',
+ help='True if you uses seat belt regularly')
+ safety = fields.Boolean(string='Car Child Safety',
+ help='True if you have car child safety')
+ home = fields.Boolean(string='Home Safety', help='True for home safety')
+ occupation = fields.Char(string='Occupation', help='Your occupation')
+
+ @api.model
+ def create(self, vals):
+ """Inherits create function for sequence generation"""
+ if vals.get('patient_seq', 'New') == 'New':
+ vals['patient_seq'] = self.env['ir.sequence'].next_by_code(
+ 'patient.sequence') or 'New'
+ return super().create(vals)
+
+ def action_view_invoice(self):
+ """Returns patient invoice"""
+ self.ensure_one()
+ return {
+ 'name': 'Patient Invoice',
+ 'view_mode': 'tree,form',
+ 'res_model': 'account.move',
+ 'type': 'ir.actions.act_window',
+ 'domain': [('partner_id', '=', self.id)],
+ 'context': "{'create':False}"
+ }
+
+ def fetch_view_id(self):
+ """Returns the view id of patient"""
+ return self.env['ir.ui.view'].sudo().search([
+ ('name', '=', 'hospital.patient.view.form')]).id
+
+ def name_get(self):
+ """Returns the patient name"""
+ result = []
+ for rec in self:
+ result.append((rec.id, f'{rec.patient_seq} - {rec.name}'))
+ return result
+
+ def alive_status(self):
+ """Function for setting the value of is_alive field"""
+ if self.is_alive == 'alive':
+ self.is_alive = 'dead'
+ else:
+ self.is_alive = 'alive'
+
+ def action_schedule(self):
+ """Returns form view of hospital appointment wizard"""
+ return {
+ 'type': 'ir.actions.act_window',
+ 'res_model': 'hospital.outpatient',
+ 'view_type': 'form',
+ 'view_mode': 'form',
+ 'target': 'new',
+ 'views': [[False, 'form']],
+ 'context': {
+ 'default_patient_id': self.id
+ }
+ }
+
+ @api.model
+ def ean_checksum(self, eancode):
+ """Returns the checksum of an ean string of length 13, returns -1 if
+ the string has the wrong length"""
+ if len(eancode) != 13:
+ return -1
+ odd_sum = 0
+ even_sum = 0
+ ean_value = eancode
+ reverse_value = ean_value[::-1]
+ final_ean = reverse_value[1:]
+ for i in range(len(final_ean)):
+ if i % 2 == 0:
+ odd_sum += int(final_ean[i])
+ else:
+ even_sum += int(final_ean[i])
+ total = (odd_sum * 3) + even_sum
+ check = int(10 - math.ceil(total % 10.0)) % 10
+ return check
+
+ def check_ean(eancode):
+ """Returns True if eancode is a valid ean13 string, or null"""
+ if not eancode:
+ return True
+ if len(eancode) != 13:
+ return False
+ int(eancode)
+ return eancode.ean_checksum(eancode) == int(eancode[-1])
+
+ def generate_ean(self, ean):
+ """Creates and returns a valid ean13 from an invalid one"""
+ if not ean:
+ return "0000000000000"
+ ean = re.sub("[A-Za-z]", "0", ean)
+ ean = re.sub("[^0-9]", "", ean)
+ ean = ean[:13]
+ if len(ean) < 13:
+ ean = ean + '0' * (13 - len(ean))
+ return ean[:-1] + str(self.ean_checksum(ean))
+
+ def action_generate_patient_card(self):
+ """Method for generating the patient card"""
+ current_age = 0
+ gender_caps = ''
+ blood_caps = ''
+ if not self.barcode:
+ ean = self.sudo().generate_ean(str(self.id))
+ self.sudo().write({'barcode': ean})
+ number = self.barcode
+ my_code = EAN13(number, writer=ImageWriter())
+ my_code.save("code")
+ with open('code.png', 'rb') as f:
+ self.sudo().write({
+ 'barcode_png': base64.b64encode(f.read())
+ })
+ if self.gender:
+ gender_caps = self.gender.capitalize()
+ if self.blood_group:
+ blood_caps = self.blood_group.capitalize()
+ if self.date_of_birth:
+ today = date.today()
+ dob = self.date_of_birth
+ current_age = relativedelta(today, dob).years
+ company = self.env['res.company'].sudo().search(
+ [('id', '=', self.env.context['allowed_company_ids'])])
+ data = {
+ 'name': self.name,
+ 'code': self.patient_seq,
+ 'age': current_age,
+ 'gender': gender_caps,
+ 'dob': self.date_of_birth,
+ 'blood': blood_caps + str(self.rh_type),
+ 'street': self.street,
+ 'street2': self.street2,
+ 'state': self.state_id.name,
+ 'country': self.country_id.name,
+ 'city': self.city,
+ 'phone': self.phone,
+ 'image': self.sudo().read(['image_1920'])[0],
+ 'barcode': self.sudo().read(['barcode_png'])[0],
+ 'company_name': company.name,
+ 'company_street': company.street,
+ 'company_street2': company.street2,
+ 'company_city': company.city,
+ 'company_state': company.state_id.name,
+ 'company_zip': company.zip,
+ }
+ return self.env.ref(
+ 'base_hospital_management.action_report_patient_card'
+ ).report_action(None, data=data)
+
+ @api.model
+ def reception_op_barcode(self, kw):
+ """Returns a patient based on the barcode"""
+ values = {
+ 'name': '',
+ 'date_of_birth': '',
+ 'phone': '',
+ 'blood_group': '',
+ 'gender': '',
+ }
+ if kw['patient_data']:
+ patient = self.sudo().search(
+ ['|', ('patient_seq', '=', kw['patient_data']),
+ ('phone', '=', kw['patient_data'])])
+ if patient:
+ values = {
+ 'name': patient.name,
+ 'date_of_birth': patient.date_of_birth,
+ 'phone': patient.phone,
+ 'blood_group': patient.blood_group,
+ 'gender': patient.gender,
+ }
+ return values
+
+ @api.model
+ def reception_op_phone(self, phone):
+ """Returns a patient details having the phone number"""
+ patient_phone = self.sudo().search(
+ [('phone', '=', phone['patient-phone'])])
+ values = {
+ 'patient_seq': patient_phone.patient_seq,
+ 'name': patient_phone.name,
+ 'date_of_birth': patient_phone.date_of_birth,
+ 'blood_group': patient_phone.blood_group,
+ 'gender': patient_phone.gender,
+ }
+ return values
+
+ @api.model
+ def action_get_patient_data(self, patient_id):
+ """Method which returns patient details"""
+ data = self.sudo().search([
+ '|', ('patient_seq', '=', patient_id.upper()),
+ ('barcode', '=', patient_id)
+ ])
+ patient_history = []
+ for rec in self.env['hospital.outpatient'].sudo().search(
+ [('patient_id', '=', data.id)]):
+ patient_history.append(
+ [rec.op_reference, str(rec.op_date),
+ rec.doctor_id.doctor_id.name])
+ values = {
+ 'name': data.name,
+ 'unique': data.patient_seq,
+ 'email': data.email,
+ 'phone': data.phone,
+ 'dob': data.date_of_birth,
+ 'image_1920': data.image_1920,
+ 'status': data.marital_status,
+ 'history': patient_history,
+ }
+ if not data.name:
+ values['name'] = 'Patient Not Found'
+ if not data.patient_seq:
+ values['unique'] = ''
+ if data.blood_group:
+ blood_caps = data.blood_group.capitalize()
+ values['blood_group'] = blood_caps + str(data.rh_type)
+ else:
+ values['blood_group'] = ''
+ if data.gender:
+ gender_caps = data.gender.capitalize()
+ values['gender'] = gender_caps
+ else:
+ values['gender'] = ''
+ return values
+
+ @api.model
+ def create_sale_order_pharmacy(self, order):
+ """Method for creating sale order for medicines"""
+ medicine = []
+ op_record = self.env['hospital.outpatient'].sudo().search(
+ [('op_reference', '=', order), '|',
+ ('active', 'in', [False, True])])
+ for rec in op_record.prescription_ids:
+ medicine.append([rec.medicine_id.id, rec.quantity])
+ sale_order_pharmacy = self.env['sale.order'].sudo().create({
+ 'partner_id': op_record.patient_id.id,
+ })
+ for new in medicine:
+ self.env['sale.order.line'].sudo().create({
+ 'product_id': new[0],
+ 'product_uom_qty': new[1],
+ 'order_id': sale_order_pharmacy.id,
+ })
+
+ @api.model
+ def create_patient(self, post):
+ """Method for creating a patient"""
+ if post and not post['id']:
+ patient = self.sudo().create({
+ 'name': post['op_name'],
+ 'blood_group': post['op_blood_group'],
+ 'gender': post['op_gender']
+ })
+ if 'op_dob' in post.keys():
+ patient.sudo().write({'date_of_birth': post['op_dob']})
+ else:
+ patient = self.sudo().search([('patient_seq', '=', post['id'])])
+ self.env['hospital.outpatient'].sudo().create({
+ 'patient_id': patient.id,
+ 'op_date': post['date'],
+ 'reason': post['reason'],
+ 'slot': post['slot'],
+ 'doctor_id': self.env['doctor.allocation'].sudo().browse(
+ post['doctor']).id
+ })
+
+ def fetch_patient_data(self):
+ """Method for returning patient data"""
+ return self.sudo().search_read(
+ [('patient_seq', 'not in', ['New', 'Employee', 'User'])])
diff --git a/base_hospital_management/models/res_users.py b/base_hospital_management/models/res_users.py
new file mode 100755
index 000000000..f8e77518a
--- /dev/null
+++ b/base_hospital_management/models/res_users.py
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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, models
+
+
+class ResUsers(models.Model):
+ """Inherited to prevent creating patients while creating users"""
+ _inherit = 'res.users'
+
+ @api.model_create_multi
+ def create(self, vals_list):
+ """Override to add patient_seq to the partners created from users"""
+ users = super().create(vals_list)
+ for user in users:
+ user.partner_id.patient_seq = 'User'
+ return users
diff --git a/base_hospital_management/models/room_facility.py b/base_hospital_management/models/room_facility.py
new file mode 100755
index 000000000..de2eed38b
--- /dev/null
+++ b/base_hospital_management/models/room_facility.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+################################################################################
+#
+# Cybrosys Technologies Pvt. Ltd.
+#
+# Copyright (C) 2023-TODAY Cybrosys Technologies().
+# Author: Cybrosys Techno Solutions (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 RoomFacility(models.Model):
+ """Class holding room facilities"""
+ _name = 'room.facility'
+ _description = 'Room Facility'
+
+ name = fields.Char(string="Facilities", help='Name of room facility')
diff --git a/base_hospital_management/report/lab_test_line_reports.xml b/base_hospital_management/report/lab_test_line_reports.xml
new file mode 100755
index 000000000..4e96823ad
--- /dev/null
+++ b/base_hospital_management/report/lab_test_line_reports.xml
@@ -0,0 +1,66 @@
+
+
+
+
+ Patient Lab Tests
+ lab.test.line
+ qweb-pdf
+
+ base_hospital_management.report_patient_lab_tests
+
+
+ base_hospital_management.report_patient_lab_tests
+
+
+ report
+
+
+
+
+
+
+
+
+
+
diff --git a/base_hospital_management/security/base_hospital_management_groups.xml b/base_hospital_management/security/base_hospital_management_groups.xml
new file mode 100755
index 000000000..8fdb1bc69
--- /dev/null
+++ b/base_hospital_management/security/base_hospital_management_groups.xml
@@ -0,0 +1,42 @@
+
+
+
+
+ Hospital Management
+ User access levels for Hospital Management
+
+ 10
+
+
+
+ Lab Assistant
+
+
+
+
+ Pharmacist
+
+
+
+
+ Nurse
+
+
+
+
+ Doctor
+
+
+
+
+ Receptionist
+
+
+
+
+ Manager
+
+
+
diff --git a/base_hospital_management/security/doctor_allocation_security.xml b/base_hospital_management/security/doctor_allocation_security.xml
new file mode 100755
index 000000000..80d10f1a0
--- /dev/null
+++ b/base_hospital_management/security/doctor_allocation_security.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+ Doctor Allocation Rule Doctor
+
+
+ [('doctor_id.user_id','=',user.id)]
+
+
+
+
+
+ Doctor Allocation Rule Manager
+
+
+ [(1,'=',1)]
+
+
+
+
+
+ Doctor Allocation Rule Company
+
+
+ ['|',('company_id','=',False),('company_id', 'in', company_ids)]
+
+
+
+
diff --git a/base_hospital_management/security/doctor_slot_security.xml b/base_hospital_management/security/doctor_slot_security.xml
new file mode 100755
index 000000000..7550b182e
--- /dev/null
+++ b/base_hospital_management/security/doctor_slot_security.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+ Doctor Slot Rule Doctor
+
+
+ [('doctor_id.user_id','=',user.id)]
+
+
+
+
+
+ Doctor Slot Rule Company
+
+
+ ['|',('company_id','=',False),('company_id', 'in', company_ids)]
+
+
+
+
+
diff --git a/base_hospital_management/security/ir.model.access.csv b/base_hospital_management/security/ir.model.access.csv
new file mode 100755
index 000000000..168e9e1eb
--- /dev/null
+++ b/base_hospital_management/security/ir.model.access.csv
@@ -0,0 +1,214 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+
+access_medicine_brand_lab_assistant,access.medicine.brand_lab.assistant,model_medicine_brand,base_hospital_management.base_hospital_management_group_lab_assistant,1,1,0,0
+access_medicine_brand_pharmacist,access.medicine.brand.pharmacist,model_medicine_brand,base_hospital_management.base_hospital_management_group_pharmacist,1,1,1,1
+access_medicine_brand_nurse,access.medicine.brand.nurse,model_medicine_brand,base_hospital_management.base_hospital_management_group_nurse,1,1,0,0
+access_medicine_brand_doctor,access.medicine.brand.doctor,model_medicine_brand,base_hospital_management.base_hospital_management_group_doctor,1,1,1,1
+access_medicine_brand_receptionist,access.medicine.brand.receptionist,model_medicine_brand,base_hospital_management.base_hospital_management_group_receptionist,1,1,1,0
+access_medicine_brand_manager,access.medicine.brand.manager,model_medicine_brand,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_doctor_specialization_lab_assistant,access.doctor.specialization.lab.assistant,model_doctor_specialization,base_hospital_management.base_hospital_management_group_lab_assistant,1,1,0,0
+access_doctor_specialization_pharmacist,access.doctor.specialization.pharmacist,model_doctor_specialization,base_hospital_management.base_hospital_management_group_pharmacist,1,1,0,0
+access_doctor_specialization_nurse,access.doctor.specialization.nurse,model_doctor_specialization,base_hospital_management.base_hospital_management_group_nurse,1,1,1,0
+access_doctor_specialization_doctor,model_doctor_specialization,model_doctor_specialization,base_hospital_management.base_hospital_management_group_doctor,1,1,1,0
+access_doctor_specialization_receptionist,model_doctor_specialization,model_doctor_specialization,base_hospital_management.base_hospital_management_group_receptionist,1,1,1,0
+access_doctor_specialization_manager,model_doctor_specialization,model_doctor_specialization,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_contra_indication_lab_assistant,access.contra.indication.lab.assistant,model_contra_indication,base_hospital_management.base_hospital_management_group_lab_assistant,1,1,0,0
+access_contra_indication_pharmacist,access.contra.indication.pharmacist,model_contra_indication,base_hospital_management.base_hospital_management_group_pharmacist,1,1,1,0
+access_contra_indication_nurse,access.contra.indication.nurse,model_contra_indication,base_hospital_management.base_hospital_management_group_nurse,1,1,1,0
+access_contra_indication_doctor,access.contra.indication.doctor,model_contra_indication,base_hospital_management.base_hospital_management_group_doctor,1,1,1,0
+access_contra_indication_receptionist,access.contra.indication.receptionist,model_contra_indication,base_hospital_management.base_hospital_management_group_receptionist,1,1,1,1
+access_contra_indication_manager,access.contra.indication.manager,model_contra_indication,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_hospital_degree_lab_assistant,access.hospital.degree.lab.assistant,model_hospital_degree,base_hospital_management.base_hospital_management_group_lab_assistant,1,0,0,0
+access_hospital_degree_pharmacist,access.hospital.degree.pharmacist,model_hospital_degree,base_hospital_management.base_hospital_management_group_pharmacist,1,0,0,0
+access_hospital_degree_nurse,access.hospital.degree.nurse,model_hospital_degree,base_hospital_management.base_hospital_management_group_nurse,1,1,0,0
+access_hospital_degree_doctor,access.hospital.degree.doctor,model_hospital_degree,base_hospital_management.base_hospital_management_group_doctor,1,0,0,0
+access_hospital_degree_receptionist,access.hospital.degree.receptionist,model_hospital_degree,base_hospital_management.base_hospital_management_group_receptionist,1,1,1,0
+access_hospital_degree_manager,access.hospital.degree.manager,model_hospital_degree,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_room_facility_lab_assistant,access.room.facility.lab.assistant,model_room_facility,base_hospital_management.base_hospital_management_group_lab_assistant,1,1,0,0
+access_room_facility_pharmacist,access.room.facility.pharmacist,model_room_facility,base_hospital_management.base_hospital_management_group_pharmacist,1,1,0,0
+access_room_facility_nurse,access.room.facility.nurse,model_room_facility,base_hospital_management.base_hospital_management_group_nurse,1,1,0,0
+access_room_facility_doctor,access.room.facility.doctor,model_room_facility,base_hospital_management.base_hospital_management_group_doctor,1,0,0,0
+access_room_facility_receptionist,access.room.facility.receptionist,model_room_facility,base_hospital_management.base_hospital_management_group_receptionist,1,1,1,1
+access_room_facility_manager,access.room.facility.manager,model_room_facility,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_hospital_laboratory_lab_assistant,access.hospital.laboratory.lab.assistant,model_hospital_laboratory,base_hospital_management.base_hospital_management_group_lab_assistant,1,1,1,0
+access_hospital_laboratory_pharmacist,access.hospital.laboratory.pharmacist,model_hospital_laboratory,base_hospital_management.base_hospital_management_group_pharmacist,1,1,0,0
+access_hospital_laboratory_nurse,access.hospital.laboratory.nurse,model_hospital_laboratory,base_hospital_management.base_hospital_management_group_nurse,1,1,0,0
+access_hospital_laboratory_doctor,access.hospital.laboratory.doctor,model_hospital_laboratory,base_hospital_management.base_hospital_management_group_doctor,1,1,0,0
+access_hospital_laboratory_receptionist,access.hospital.laboratory.receptionist,model_hospital_laboratory,base_hospital_management.base_hospital_management_group_receptionist,1,1,0,0
+access_hospital_laboratory_manager,access.hospital.laboratory.manager,model_hospital_laboratory,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_lab_test_lab_assistant,access.lab.test.lab.assistant,model_lab_test,base_hospital_management.base_hospital_management_group_lab_assistant,1,1,1,0
+access_lab_test_pharmacist,access.lab.test.pharmacist,model_lab_test,base_hospital_management.base_hospital_management_group_pharmacist,1,1,0,0
+access_lab_test_nurse,access.lab.test.nurse,model_lab_test,base_hospital_management.base_hospital_management_group_nurse,1,1,0,0
+access_lab_test_doctor,access.lab.test.doctor,model_lab_test,base_hospital_management.base_hospital_management_group_doctor,1,1,0,0
+access_lab_test_receptionist,access.lab.test.receptionist,model_lab_test,base_hospital_management.base_hospital_management_group_receptionist,1,1,1,0
+access_lab_test_manager,access.lab.test.manager,model_lab_test,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_doctor_slot_lab_assistant,access.doctor.slot.lab.assistant,model_doctor_slot,base_hospital_management.base_hospital_management_group_lab_assistant,1,0,0,0
+access_doctor_slot_pharmacist,access.doctor.slot.pharmacist,model_doctor_slot,base_hospital_management.base_hospital_management_group_pharmacist,1,1,0,0
+access_doctor_slot_nurse,access.doctor.slot.nurse,model_doctor_slot,base_hospital_management.base_hospital_management_group_nurse,1,1,1,0
+access_doctor_slot_doctor,access.doctor.slot.doctor,model_doctor_slot,base_hospital_management.base_hospital_management_group_doctor,1,1,1,0
+access_doctor_slot_receptionist,access.doctor.slot.receptionist,model_doctor_slot,base_hospital_management.base_hospital_management_group_receptionist,1,1,1,0
+access_doctor_slot_manager,access.doctor.slot.manager,model_doctor_slot,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_hospital_pharmacy_lab_assistant,access.hospital.pharmacy.lab.assistant,model_hospital_pharmacy,base_hospital_management.base_hospital_management_group_lab_assistant,1,1,0,0
+access_hospital_pharmacy_pharmacist,access.hospital.pharmacy.pharmacist,model_hospital_pharmacy,base_hospital_management.base_hospital_management_group_pharmacist,1,1,1,0
+access_hospital_pharmacy_nurse,access.hospital.pharmacy.nurse,model_hospital_pharmacy,base_hospital_management.base_hospital_management_group_nurse,1,1,0,0
+access_hospital_pharmacy_doctor,access.hospital.pharmacy.doctor,model_hospital_pharmacy,base_hospital_management.base_hospital_management_group_doctor,1,1,0,0
+access_hospital_pharmacy_receptionist,access.hospital.pharmacy.receptionist,model_hospital_pharmacy,base_hospital_management.base_hospital_management_group_receptionist,1,1,0,0
+access_hospital_pharmacy_manager,access.hospital.pharmacy.manager,model_hospital_pharmacy,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_pharmacy_medicine_manager,access.pharmacy.medicine.manager,model_pharmacy_medicine,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+access_pharmacy_pharmacist,access.pharmacy.medicine.pharmacist,model_pharmacy_medicine,base_hospital_management.base_hospital_management_group_pharmacist,1,1,1,1
+access_hospital_building_lab_assistant,access.hospital.building.lab.assistant,model_hospital_building,base_hospital_management.base_hospital_management_group_lab_assistant,1,1,0,0
+access_hospital_building_pharmacist,access.hospital.building.pharmacist,model_hospital_building,base_hospital_management.base_hospital_management_group_pharmacist,1,1,0,0
+access_hospital_building_nurse,access.hospital.building.nurse,model_hospital_building,base_hospital_management.base_hospital_management_group_nurse,1,1,0,0
+access_hospital_building_doctor,access.hospital.building.doctor,model_hospital_building,base_hospital_management.base_hospital_management_group_doctor,1,1,0,0
+access_hospital_building_receptionist,access.hospital.building.receptionist,model_hospital_building,base_hospital_management.base_hospital_management_group_receptionist,1,1,1,0
+access_hospital_building_manager,access.hospital.building.manager,model_hospital_building,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_patient_room_lab_assistant,access.patient.room.lab.assistant,model_patient_room,base_hospital_management.base_hospital_management_group_lab_assistant,1,1,0,0
+access_patient_room_pharmacist,access.patient.room.pharmacist,model_patient_room,base_hospital_management.base_hospital_management_group_pharmacist,1,1,0,0
+access_patient_room_nurse,access.patient.room.nurse,model_patient_room,base_hospital_management.base_hospital_management_group_nurse,1,1,0,0
+access_patient_room_doctor,access.patient.room.doctor,model_patient_room,base_hospital_management.base_hospital_management_group_doctor,1,1,0,0
+access_patient_room_receptionist,access.patient.room.receptionist,model_patient_room,base_hospital_management.base_hospital_management_group_receptionist,1,1,1,0
+access_patient_room_manager,access.patient.room.manager,model_patient_room,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_hospital_ward_lab_assistant,access.hospital.ward.lab.assistant,model_hospital_ward,base_hospital_management.base_hospital_management_group_lab_assistant,1,1,0,0
+access_hospital_ward_pharmacist,access.hospital.ward.pharmacist,model_hospital_ward,base_hospital_management.base_hospital_management_group_pharmacist,1,1,0,0
+access_hospital_ward_nurse,access.hospital.ward.nurse,model_hospital_ward,base_hospital_management.base_hospital_management_group_nurse,1,1,0,0
+access_hospital_ward_doctor,access.hospital.ward.doctor,model_hospital_ward,base_hospital_management.base_hospital_management_group_doctor,1,1,0,0
+access_hospital_ward_receptionist,access.hospital.ward.receptionist,model_hospital_ward,base_hospital_management.base_hospital_management_group_receptionist,1,1,1,0
+access_hospital_ward_manager,access.hospital.ward.manager,model_hospital_ward,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_hospital_bed_lab_assistant,access.hospital.bed.lab.assistant,model_hospital_bed,base_hospital_management.base_hospital_management_group_lab_assistant,1,0,0,0
+access_hospital_bed_pharmacist,access.hospital.bed.pharmacist,model_hospital_bed,base_hospital_management.base_hospital_management_group_pharmacist,1,0,0,0
+access_hospital_bed_nurse,access.hospital.bed.nurse,model_hospital_bed,base_hospital_management.base_hospital_management_group_nurse,1,0,0,0
+access_hospital_bed_doctor,access.hospital.bed.doctor,model_hospital_bed,base_hospital_management.base_hospital_management_group_doctor,1,0,0,0
+access_hospital_bed_receptionist,access.hospital.bed.receptionist,model_hospital_bed,base_hospital_management.base_hospital_management_group_receptionist,1,1,1,0
+access_hospital_bed_manager,access.hospital.bed.manager,model_hospital_bed,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_hospital_inpatient_lab_assistant,access.hospital.inpatient.lab.assistant,model_hospital_inpatient,base_hospital_management.base_hospital_management_group_lab_assistant,1,0,0,0
+access_hospital_inpatient_pharmacist,access.hospital.inpatient.pharmacist,model_hospital_inpatient,base_hospital_management.base_hospital_management_group_pharmacist,1,0,0,0
+access_hospital_inpatient_nurse,access.hospital.inpatient.nurse,model_hospital_inpatient,base_hospital_management.base_hospital_management_group_nurse,1,1,1,0
+access_hospital_inpatient_doctor,access.hospital.inpatient.doctor,model_hospital_inpatient,base_hospital_management.base_hospital_management_group_doctor,1,1,1,0
+access_hospital_inpatient_receptionist,access.hospital.inpatient.receptionist,model_hospital_inpatient,base_hospital_management.base_hospital_management_group_receptionist,1,1,1,0
+access_hospital_inpatient_manager,access.hospital.inpatient.manager,model_hospital_inpatient,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_blood_bank_lab_assistant,access.blood.bank.lab.assistant,model_blood_bank,base_hospital_management.base_hospital_management_group_lab_assistant,1,1,0,0
+access_blood_bank_pharmacist,access.blood.bank.pharmacist,model_blood_bank,base_hospital_management.base_hospital_management_group_pharmacist,1,1,0,0
+access_blood_bank_nurse,access.blood.bank.nurse,model_blood_bank,base_hospital_management.base_hospital_management_group_nurse,1,0,0,0
+access_blood_bank_doctor,access.blood.bank.doctor,model_blood_bank,base_hospital_management.base_hospital_management_group_doctor,1,1,1,0
+access_blood_bank_receptionist,access.blood.bank.receptionist,model_blood_bank,base_hospital_management.base_hospital_management_group_receptionist,1,1,1,0
+access_blood_bank_manager,access.blood.bank.manager,model_blood_bank,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_hospital_outpatient_lab_assistant,access.hospital.outpatient.lab.assistant,model_hospital_outpatient,base_hospital_management.base_hospital_management_group_lab_assistant,1,1,1,0
+access_hospital_outpatient_pharmacist,access.hospital.outpatient.pharmacist,model_hospital_outpatient,base_hospital_management.base_hospital_management_group_pharmacist,1,1,1,0
+access_hospital_outpatient_nurse,access.hospital.outpatient.model_hospital_outpatient,model_hospital_outpatient,base_hospital_management.base_hospital_management_group_nurse,1,1,1,0
+access_hospital_outpatient_doctor,access.hospital.outpatient.doctor,model_hospital_outpatient,base_hospital_management.base_hospital_management_group_doctor,1,1,1,0
+access_hospital_outpatient_receptionist,access.hospital.outpatient.receptionist,model_hospital_outpatient,base_hospital_management.base_hospital_management_group_receptionist,1,1,1,0
+access_hospital_outpatient_manager,access.hospital.outpatient.manager,model_hospital_outpatient,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_hospital_insurance_lab_assistant,access.hospital.insurance.lab.assistant,model_hospital_insurance,base_hospital_management.base_hospital_management_group_lab_assistant,1,1,0,0
+access_hospital_insurance_pharmacist,access.hospital.insurance.pharmacist,model_hospital_insurance,base_hospital_management.base_hospital_management_group_pharmacist,1,1,0,0
+access_hospital_insurance_nurse,access.hospital.insurance.nurse,model_hospital_insurance,base_hospital_management.base_hospital_management_group_nurse,1,1,0,0
+access_hospital_insurance_doctor,access.hospital.insurance.doctor,model_hospital_insurance,base_hospital_management.base_hospital_management_group_doctor,1,0,0,0
+access_hospital_insurance_receptionist,access.hospital.insurance.receptionist,model_hospital_insurance,base_hospital_management.base_hospital_management_group_receptionist,1,1,1,0
+access_hospital_insurance_manager,access.hospital.insurance.manager,model_hospital_insurance,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_hospital_family_lab_assistant,access.hospital.family.lab.assistant,model_hospital_family,base_hospital_management.base_hospital_management_group_lab_assistant,1,1,0,0
+access_hospital_family_pharmacist,access.hospital.family.pharmacist,model_hospital_family,base_hospital_management.base_hospital_management_group_pharmacist,1,1,0,0
+access_hospital_family_nurse,access.hospital.family.nurse,model_hospital_family,base_hospital_management.base_hospital_management_group_nurse,1,1,0,0
+access_hospital_family_doctor,access.hospital.family.doctor,model_hospital_family,base_hospital_management.base_hospital_management_group_doctor,1,1,0,0
+access_hospital_family_receptionist,access.hospital.family.receptionist,model_hospital_family,base_hospital_management.base_hospital_management_group_receptionist,1,1,1,0
+access_hospital_family_manager,access.hospital.family.manager,model_hospital_family,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_hospital_vaccination_lab_assistant,access.hospital.vaccination.lab.assistant,model_hospital_vaccination,base_hospital_management.base_hospital_management_group_lab_assistant,1,1,1,1
+access_hospital_vaccination_pharmacist,access.hospital.vaccination.pharmacist,model_hospital_vaccination,base_hospital_management.base_hospital_management_group_pharmacist,1,1,1,0
+access_hospital_vaccination_nurse,access.hospital.vaccination.nurse,model_hospital_vaccination,base_hospital_management.base_hospital_management_group_nurse,1,1,0,0
+access_hospital_vaccination_doctor,access.hospital.vaccination.doctor,model_hospital_vaccination,base_hospital_management.base_hospital_management_group_doctor,1,1,1,0
+access_hospital_vaccination_receptionist,access.hospital.vaccination.receptionist,model_hospital_vaccination,base_hospital_management.base_hospital_management_group_receptionist,1,1,0,0
+access_hospital_vaccination_manager,access.hospital.vaccination.manager,model_hospital_vaccination,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_lab_test_line_lab_assistant,access.lab.test.line.lab.assistant,model_lab_test_line,base_hospital_management.base_hospital_management_group_lab_assistant,1,1,1,0
+access_lab_test_line_pharmacist,access.lab.test.line.pharmacist,model_lab_test_line,base_hospital_management.base_hospital_management_group_pharmacist,1,1,0,0
+access_lab_test_line_nurse,access.lab.test.line.nurse,model_lab_test_line,base_hospital_management.base_hospital_management_group_nurse,1,1,1,0
+access_lab_test_line_doctor,access.lab.test.line.doctor,model_lab_test_line,base_hospital_management.base_hospital_management_group_doctor,1,1,0,0
+access_lab_test_line_receptionist,access.lab.test.line.receptionist,model_lab_test_line,base_hospital_management.base_hospital_management_group_receptionist,1,1,1,0
+access_lab_test_line_lab_tests_manager,access.lab.test.line.manager,model_lab_test_line,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_lab_test_result_lab_assistant,access.lab.test.result.lab.assistant,model_lab_test_result,base_hospital_management.base_hospital_management_group_lab_assistant,1,1,1,0
+access_lab_test_result_pharmacist,access.lab.test.result.pharmacist,model_lab_test_result,base_hospital_management.base_hospital_management_group_pharmacist,1,1,0,0
+access_lab_test_result_nurse,access.lab.test.result.nurse,model_lab_test_result,base_hospital_management.base_hospital_management_group_nurse,1,1,0,0
+access_lab_test_result_doctor,access.lab.test.result.doctor,model_lab_test_result,base_hospital_management.base_hospital_management_group_doctor,1,1,0,0
+access_lab_test_result_receptionist,access.lab.test.result.receptionist,model_lab_test_result,base_hospital_management.base_hospital_management_group_receptionist,1,1,1,0
+access_lab_test_result_manager,access.lab.test.result.manager,model_lab_test_result,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_doctor_allocation_lab_assistant,access.doctor.allocation.lab.assistant,model_doctor_allocation,base_hospital_management.base_hospital_management_group_lab_assistant,1,1,0,0
+access_doctor_allocation_pharmacist,access.doctor.allocation.pharmacist,model_doctor_allocation,base_hospital_management.base_hospital_management_group_pharmacist,1,1,0,0
+access_doctor_allocation_nurse,access.doctor.allocation.nurse,model_doctor_allocation,base_hospital_management.base_hospital_management_group_nurse,1,1,0,0
+access_doctor_allocation_doctor,access.doctor.allocation.doctor,model_doctor_allocation,base_hospital_management.base_hospital_management_group_doctor,1,1,1,0
+access_doctor_allocation_receptionist,access.doctor.allocation.receptionist,model_doctor_allocation,base_hospital_management.base_hospital_management_group_receptionist,1,1,1,0
+access_doctor_allocation_manager,access.doctor.allocation.manager,model_doctor_allocation,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+access_doctor_allocation_portal,access.doctor.allocation.portal,model_doctor_allocation,base.group_portal,1,0,0,0
+
+access_lab_medicine_line_lab_assistant,access.lab.medicine.line.lab.assistant,model_lab_medicine_line,base_hospital_management.base_hospital_management_group_lab_assistant,1,1,1,0
+access_lab_medicine_line_pharmacist,access.lab.medicine.line.pharmacist,model_lab_medicine_line,base_hospital_management.base_hospital_management_group_pharmacist,1,1,1,0
+access_lab_medicine_line_nurse,access.lab.medicine.line.nurse,model_lab_medicine_line,base_hospital_management.base_hospital_management_group_nurse,1,1,0,0
+access_lab_medicine_line_doctor,access.lab.medicine.line.doctor,model_lab_medicine_line,base_hospital_management.base_hospital_management_group_doctor,1,1,0,0
+access_lab_medicine_line_receptionist,access.lab.medicine.line.receptionist,model_lab_medicine_line,base_hospital_management.base_hospital_management_group_receptionist,1,1,1,0
+access_lab_medicine_line_manager,access.lab.medicine.line.manager,model_lab_medicine_line,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_nursing_plan_lab_assistant,access.nursing.plan.lab.assistant,model_nursing_plan,base_hospital_management.base_hospital_management_group_lab_assistant,1,1,0,0
+access_nursing_plan_pharmacist,access.nursing.plan.pharmacist,model_nursing_plan,base_hospital_management.base_hospital_management_group_pharmacist,1,1,0,0
+access_nursing_plan_nurse,access.nursing.plan.nurse,model_nursing_plan,base_hospital_management.base_hospital_management_group_nurse,1,1,1,0
+access_nursing_plan_doctor,access.nursing.plan.doctor,model_nursing_plan,base_hospital_management.base_hospital_management_group_doctor,1,1,1,0
+access_nursing_plan_receptionist,access.nursing.plan.receptionist,model_nursing_plan,base_hospital_management.base_hospital_management_group_receptionist,1,1,1,0
+access_nursing_plan_manager,access.nursing.plan.manager,model_nursing_plan,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_doctor_round_lab_assistant,access.doctor.round.lab.assistant,model_doctor_round,base_hospital_management.base_hospital_management_group_lab_assistant,1,0,0,0
+access_doctor_round_pharmacist,access.doctor.round.pharmacist,model_doctor_round,base_hospital_management.base_hospital_management_group_pharmacist,1,0,0,0
+access_doctor_round_nurse,access.doctor.round.nurse,model_doctor_round,base_hospital_management.base_hospital_management_group_nurse,1,1,1,1
+access_doctor_round_doctor,access.doctor.round.doctor,model_doctor_round,base_hospital_management.base_hospital_management_group_doctor,1,1,1,1
+access_doctor_round_receptionist,access.doctor.round.receptionist,model_doctor_round,base_hospital_management.base_hospital_management_group_receptionist,1,1,1,1
+access_doctor_round_manager,access.doctor.round.manager,model_doctor_round,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_prescription_line_lab_assistant,access.prescription.line.lab.assistant,model_prescription_line,base_hospital_management.base_hospital_management_group_lab_assistant,1,1,0,0
+access_prescription_line_pharmacist,access.prescription.line.pharmacist,model_prescription_line,base_hospital_management.base_hospital_management_group_pharmacist,1,1,1,0
+access_prescription_line_nurse,access.prescription.line.nurse,model_prescription_line,base_hospital_management.base_hospital_management_group_nurse,1,1,1,0
+access_prescription_line_doctor,access.prescription.line.doctor,model_prescription_line,base_hospital_management.base_hospital_management_group_doctor,1,1,1,0
+access_prescription_line_receptionist,access.prescription.line.receptionist,model_prescription_line,base_hospital_management.base_hospital_management_group_receptionist,1,1,1,1
+access_prescription_line_manager,access.prescription.line.manager,model_prescription_line,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_blood_donation_lab_assistant,access.blood.donation.lab.assistant,model_blood_donation,base_hospital_management.base_hospital_management_group_lab_assistant,1,1,0,0
+access_blood_donation_pharmacist,access.blood.donation.lab.pharmacist,model_blood_donation,base_hospital_management.base_hospital_management_group_pharmacist,1,1,1,0
+access_blood_donation_nurse,access.blood.donation.lab.nurse,model_blood_donation,base_hospital_management.base_hospital_management_group_nurse,1,1,1,0
+access_blood_donation_doctor,access.blood.donation.lab.doctor,model_blood_donation,base_hospital_management.base_hospital_management_group_doctor,1,1,1,0
+access_blood_donation_receptionist,access.blood.donation.lab.receptionist,model_blood_donation,base_hospital_management.base_hospital_management_group_receptionist,1,1,1,1
+access_blood_donation_manager,access.blood.donation.lab.manager,model_blood_donation,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_inpatient_payment_lab_assistant,access.inpatient.payment.lab.assistant,model_inpatient_payment,base_hospital_management.base_hospital_management_group_lab_assistant,1,1,0,0
+access_inpatient_payment_pharmacist,access.inpatient.payment.pharmacist,model_inpatient_payment,base_hospital_management.base_hospital_management_group_pharmacist,1,1,1,0
+access_inpatient_payment_nurse,access.inpatient.payment.nurse,model_inpatient_payment,base_hospital_management.base_hospital_management_group_nurse,1,1,1,0
+access_inpatient_payment_doctor,access.inpatient.payment.doctor,model_inpatient_payment,base_hospital_management.base_hospital_management_group_doctor,1,1,1,0
+access_inpatient_payment_receptionist,access.inpatient.payment.receptionis,model_inpatient_payment,base_hospital_management.base_hospital_management_group_receptionist,1,1,1,1
+access_inpatient_payment_manager,access.inpatient.payment.manager,model_inpatient_payment,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_inpatient_surgery_lab_assistant,access.inpatient.surgery.lab.assistant,model_inpatient_surgery,base_hospital_management.base_hospital_management_group_lab_assistant,1,1,0,0
+access_inpatient_surgery_pharmacist,access.inpatient.surgery.pharmacist,model_inpatient_surgery,base_hospital_management.base_hospital_management_group_pharmacist,1,1,1,0
+access_inpatient_surgery_nurse,access.inpatient.surgery.nurse,model_inpatient_surgery,base_hospital_management.base_hospital_management_group_nurse,1,1,1,0
+access_inpatient_surgery_doctor,access.inpatient.surgery.doctor,model_inpatient_surgery,base_hospital_management.base_hospital_management_group_doctor,1,1,1,0
+access_inpatient_surgery_receptionist,access.inpatient.surgery.receptionist,model_inpatient_surgery,base_hospital_management.base_hospital_management_group_receptionist,1,1,1,1
+access_inpatient_surgery_manager,access.inpatient.surgery.manager,model_inpatient_surgery,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
+
+access_patient_lab_test_lab_assistant,access.patient.lab.test.lab.assistant,model_patient_lab_test,base_hospital_management.base_hospital_management_group_lab_assistant,1,1,0,0
+access_patient_lab_test_pharmacist,access.patient.lab.test.pharmacist,model_patient_lab_test,base_hospital_management.base_hospital_management_group_pharmacist,1,1,0,0
+access_patient_lab_test_nurse,access.patient.lab.test.nurse,model_patient_lab_test,base_hospital_management.base_hospital_management_group_nurse,1,1,0,0
+access_patient_lab_test_doctor,access.patient.lab.test.doctor,model_patient_lab_test,base_hospital_management.base_hospital_management_group_doctor,1,1,0,0
+access_patient_lab_test_receptionist,access.patient.lab.test.receptionist,model_patient_lab_test,base_hospital_management.base_hospital_management_group_receptionist,1,1,1,1
+access_patient_lab_test_manager,access.patient.lab.test.manager,model_patient_lab_test,base_hospital_management.base_hospital_management_group_manager,1,1,1,1
diff --git a/base_hospital_management/security/patient_booking_security.xml b/base_hospital_management/security/patient_booking_security.xml
new file mode 100755
index 000000000..fbe7fad1e
--- /dev/null
+++ b/base_hospital_management/security/patient_booking_security.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+ Patient Booking Rule Doctor
+
+
+ [('doctor_id.doctor_id.user_id','=',user.id)]
+
+
+
+
+
+ Patient Booking Rule Company
+
+
+ ['|',('company_id','=',False),('company_id', 'in', company_ids)]
+
+
+
+
diff --git a/base_hospital_management/security/patient_lab_test_security.xml b/base_hospital_management/security/patient_lab_test_security.xml
new file mode 100755
index 000000000..a5c9cac48
--- /dev/null
+++ b/base_hospital_management/security/patient_lab_test_security.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+ Patient Lab Test Rule Lab Assistant
+
+
+ ['|','|',('lab_id.technician_id.user_id','=',user.id),('lab_id.technician_id.user_id','=',False),('lab_id','=',False)]
+
+
+
+
+
+ Patient Lab Test Rule Company
+
+
+ ['|',('company_id','=',False),('company_id', 'in', company_ids)]
+
+
+
+
diff --git a/base_hospital_management/static/description/assets/icons/check.png b/base_hospital_management/static/description/assets/icons/check.png
new file mode 100755
index 000000000..c8e85f51d
Binary files /dev/null and b/base_hospital_management/static/description/assets/icons/check.png differ
diff --git a/base_hospital_management/static/description/assets/icons/chevron.png b/base_hospital_management/static/description/assets/icons/chevron.png
new file mode 100755
index 000000000..2089293d6
Binary files /dev/null and b/base_hospital_management/static/description/assets/icons/chevron.png differ
diff --git a/base_hospital_management/static/description/assets/icons/cogs.png b/base_hospital_management/static/description/assets/icons/cogs.png
new file mode 100755
index 000000000..95d0bad62
Binary files /dev/null and b/base_hospital_management/static/description/assets/icons/cogs.png differ
diff --git a/base_hospital_management/static/description/assets/icons/consultation.png b/base_hospital_management/static/description/assets/icons/consultation.png
new file mode 100755
index 000000000..8319d4baa
Binary files /dev/null and b/base_hospital_management/static/description/assets/icons/consultation.png differ
diff --git a/base_hospital_management/static/description/assets/icons/ecom-black.png b/base_hospital_management/static/description/assets/icons/ecom-black.png
new file mode 100755
index 000000000..a9385ff13
Binary files /dev/null and b/base_hospital_management/static/description/assets/icons/ecom-black.png differ
diff --git a/base_hospital_management/static/description/assets/icons/education-black.png b/base_hospital_management/static/description/assets/icons/education-black.png
new file mode 100755
index 000000000..3eb09b27b
Binary files /dev/null and b/base_hospital_management/static/description/assets/icons/education-black.png differ
diff --git a/base_hospital_management/static/description/assets/icons/hotel-black.png b/base_hospital_management/static/description/assets/icons/hotel-black.png
new file mode 100755
index 000000000..130f613be
Binary files /dev/null and b/base_hospital_management/static/description/assets/icons/hotel-black.png differ
diff --git a/base_hospital_management/static/description/assets/icons/license.png b/base_hospital_management/static/description/assets/icons/license.png
new file mode 100755
index 000000000..a5869797e
Binary files /dev/null and b/base_hospital_management/static/description/assets/icons/license.png differ
diff --git a/base_hospital_management/static/description/assets/icons/lifebuoy.png b/base_hospital_management/static/description/assets/icons/lifebuoy.png
new file mode 100755
index 000000000..658d56ccc
Binary files /dev/null and b/base_hospital_management/static/description/assets/icons/lifebuoy.png differ
diff --git a/base_hospital_management/static/description/assets/icons/manufacturing-black.png b/base_hospital_management/static/description/assets/icons/manufacturing-black.png
new file mode 100755
index 000000000..697eb0e9f
Binary files /dev/null and b/base_hospital_management/static/description/assets/icons/manufacturing-black.png differ
diff --git a/base_hospital_management/static/description/assets/icons/pos-black.png b/base_hospital_management/static/description/assets/icons/pos-black.png
new file mode 100755
index 000000000..97c0f90c1
Binary files /dev/null and b/base_hospital_management/static/description/assets/icons/pos-black.png differ
diff --git a/base_hospital_management/static/description/assets/icons/puzzle.png b/base_hospital_management/static/description/assets/icons/puzzle.png
new file mode 100755
index 000000000..65cf854e7
Binary files /dev/null and b/base_hospital_management/static/description/assets/icons/puzzle.png differ
diff --git a/base_hospital_management/static/description/assets/icons/restaurant-black.png b/base_hospital_management/static/description/assets/icons/restaurant-black.png
new file mode 100755
index 000000000..4a35eb939
Binary files /dev/null and b/base_hospital_management/static/description/assets/icons/restaurant-black.png differ
diff --git a/base_hospital_management/static/description/assets/icons/service-black.png b/base_hospital_management/static/description/assets/icons/service-black.png
new file mode 100755
index 000000000..301ab51cb
Binary files /dev/null and b/base_hospital_management/static/description/assets/icons/service-black.png differ
diff --git a/base_hospital_management/static/description/assets/icons/trading-black.png b/base_hospital_management/static/description/assets/icons/trading-black.png
new file mode 100755
index 000000000..9398ba2f1
Binary files /dev/null and b/base_hospital_management/static/description/assets/icons/trading-black.png differ
diff --git a/base_hospital_management/static/description/assets/icons/training.png b/base_hospital_management/static/description/assets/icons/training.png
new file mode 100755
index 000000000..884ca024d
Binary files /dev/null and b/base_hospital_management/static/description/assets/icons/training.png differ
diff --git a/base_hospital_management/static/description/assets/icons/update.png b/base_hospital_management/static/description/assets/icons/update.png
new file mode 100755
index 000000000..ecbc5a01a
Binary files /dev/null and b/base_hospital_management/static/description/assets/icons/update.png differ
diff --git a/base_hospital_management/static/description/assets/icons/user.png b/base_hospital_management/static/description/assets/icons/user.png
new file mode 100755
index 000000000..6ffb23d9f
Binary files /dev/null and b/base_hospital_management/static/description/assets/icons/user.png differ
diff --git a/base_hospital_management/static/description/assets/icons/wrench.png b/base_hospital_management/static/description/assets/icons/wrench.png
new file mode 100755
index 000000000..6c04dea0f
Binary files /dev/null and b/base_hospital_management/static/description/assets/icons/wrench.png differ
diff --git a/base_hospital_management/static/description/assets/misc/categories.png b/base_hospital_management/static/description/assets/misc/categories.png
new file mode 100755
index 000000000..bedf1e0b1
Binary files /dev/null and b/base_hospital_management/static/description/assets/misc/categories.png differ
diff --git a/base_hospital_management/static/description/assets/misc/check-box.png b/base_hospital_management/static/description/assets/misc/check-box.png
new file mode 100755
index 000000000..42caf24b9
Binary files /dev/null and b/base_hospital_management/static/description/assets/misc/check-box.png differ
diff --git a/base_hospital_management/static/description/assets/misc/compass.png b/base_hospital_management/static/description/assets/misc/compass.png
new file mode 100755
index 000000000..d5fed8faa
Binary files /dev/null and b/base_hospital_management/static/description/assets/misc/compass.png differ
diff --git a/base_hospital_management/static/description/assets/misc/corporate.png b/base_hospital_management/static/description/assets/misc/corporate.png
new file mode 100755
index 000000000..2eb13edbf
Binary files /dev/null and b/base_hospital_management/static/description/assets/misc/corporate.png differ
diff --git a/base_hospital_management/static/description/assets/misc/customer-support.png b/base_hospital_management/static/description/assets/misc/customer-support.png
new file mode 100755
index 000000000..79efc72ed
Binary files /dev/null and b/base_hospital_management/static/description/assets/misc/customer-support.png differ
diff --git a/base_hospital_management/static/description/assets/misc/cybrosys-logo.png b/base_hospital_management/static/description/assets/misc/cybrosys-logo.png
new file mode 100755
index 000000000..cc3cc0ccf
Binary files /dev/null and b/base_hospital_management/static/description/assets/misc/cybrosys-logo.png differ
diff --git a/base_hospital_management/static/description/assets/misc/features.png b/base_hospital_management/static/description/assets/misc/features.png
new file mode 100755
index 000000000..b41769f77
Binary files /dev/null and b/base_hospital_management/static/description/assets/misc/features.png differ
diff --git a/base_hospital_management/static/description/assets/misc/logo.png b/base_hospital_management/static/description/assets/misc/logo.png
new file mode 100755
index 000000000..478462d3e
Binary files /dev/null and b/base_hospital_management/static/description/assets/misc/logo.png differ
diff --git a/base_hospital_management/static/description/assets/misc/pictures.png b/base_hospital_management/static/description/assets/misc/pictures.png
new file mode 100755
index 000000000..56d255fe9
Binary files /dev/null and b/base_hospital_management/static/description/assets/misc/pictures.png differ
diff --git a/base_hospital_management/static/description/assets/misc/pie-chart.png b/base_hospital_management/static/description/assets/misc/pie-chart.png
new file mode 100755
index 000000000..426e05244
Binary files /dev/null and b/base_hospital_management/static/description/assets/misc/pie-chart.png differ
diff --git a/base_hospital_management/static/description/assets/misc/right-arrow.png b/base_hospital_management/static/description/assets/misc/right-arrow.png
new file mode 100755
index 000000000..730984a06
Binary files /dev/null and b/base_hospital_management/static/description/assets/misc/right-arrow.png differ
diff --git a/base_hospital_management/static/description/assets/misc/star.png b/base_hospital_management/static/description/assets/misc/star.png
new file mode 100755
index 000000000..2eb9ab29f
Binary files /dev/null and b/base_hospital_management/static/description/assets/misc/star.png differ
diff --git a/base_hospital_management/static/description/assets/misc/support.png b/base_hospital_management/static/description/assets/misc/support.png
new file mode 100755
index 000000000..4f18b8b82
Binary files /dev/null and b/base_hospital_management/static/description/assets/misc/support.png differ
diff --git a/base_hospital_management/static/description/assets/misc/whatsapp.png b/base_hospital_management/static/description/assets/misc/whatsapp.png
new file mode 100755
index 000000000..d513a5356
Binary files /dev/null and b/base_hospital_management/static/description/assets/misc/whatsapp.png differ
diff --git a/base_hospital_management/static/description/assets/modules/car.png b/base_hospital_management/static/description/assets/modules/car.png
new file mode 100755
index 000000000..3cdfc0af5
Binary files /dev/null and b/base_hospital_management/static/description/assets/modules/car.png differ
diff --git a/base_hospital_management/static/description/assets/modules/fleet.png b/base_hospital_management/static/description/assets/modules/fleet.png
new file mode 100755
index 000000000..2d2d873a7
Binary files /dev/null and b/base_hospital_management/static/description/assets/modules/fleet.png differ
diff --git a/base_hospital_management/static/description/assets/modules/lab.png b/base_hospital_management/static/description/assets/modules/lab.png
new file mode 100755
index 000000000..27d752e6e
Binary files /dev/null and b/base_hospital_management/static/description/assets/modules/lab.png differ
diff --git a/base_hospital_management/static/description/assets/modules/legal.png b/base_hospital_management/static/description/assets/modules/legal.png
new file mode 100755
index 000000000..05ed0b5ef
Binary files /dev/null and b/base_hospital_management/static/description/assets/modules/legal.png differ
diff --git a/base_hospital_management/static/description/assets/modules/library.png b/base_hospital_management/static/description/assets/modules/library.png
new file mode 100755
index 000000000..5965a8ce0
Binary files /dev/null and b/base_hospital_management/static/description/assets/modules/library.png differ
diff --git a/base_hospital_management/static/description/assets/modules/spa.png b/base_hospital_management/static/description/assets/modules/spa.png
new file mode 100755
index 000000000..4fda77f38
Binary files /dev/null and b/base_hospital_management/static/description/assets/modules/spa.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/add_doctor.png b/base_hospital_management/static/description/assets/screenshots/add_doctor.png
new file mode 100755
index 000000000..952438ac5
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/add_doctor.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/add_medicine.png b/base_hospital_management/static/description/assets/screenshots/add_medicine.png
new file mode 100755
index 000000000..309962f3b
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/add_medicine.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/add_pharmacy.png b/base_hospital_management/static/description/assets/screenshots/add_pharmacy.png
new file mode 100755
index 000000000..7a0e320c7
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/add_pharmacy.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/add_result.png b/base_hospital_management/static/description/assets/screenshots/add_result.png
new file mode 100755
index 000000000..96b5f0d4f
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/add_result.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/add_room.png b/base_hospital_management/static/description/assets/screenshots/add_room.png
new file mode 100755
index 000000000..9e72948c3
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/add_room.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/add_vaccine.png b/base_hospital_management/static/description/assets/screenshots/add_vaccine.png
new file mode 100755
index 000000000..baff252b5
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/add_vaccine.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/admit.png b/base_hospital_management/static/description/assets/screenshots/admit.png
new file mode 100755
index 000000000..3157f65ba
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/admit.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/all_op.png b/base_hospital_management/static/description/assets/screenshots/all_op.png
new file mode 100644
index 000000000..c8bf174cf
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/all_op.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/all_patients.png b/base_hospital_management/static/description/assets/screenshots/all_patients.png
new file mode 100644
index 000000000..2830810a2
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/all_patients.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/all_test.png b/base_hospital_management/static/description/assets/screenshots/all_test.png
new file mode 100755
index 000000000..fb5e7ad52
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/all_test.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/allocation.png b/base_hospital_management/static/description/assets/screenshots/allocation.png
new file mode 100755
index 000000000..373434520
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/allocation.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/appointment.png b/base_hospital_management/static/description/assets/screenshots/appointment.png
new file mode 100755
index 000000000..c9a6493a2
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/appointment.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/booking.png b/base_hospital_management/static/description/assets/screenshots/booking.png
new file mode 100755
index 000000000..6629558d4
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/booking.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/booking_tab.png b/base_hospital_management/static/description/assets/screenshots/booking_tab.png
new file mode 100755
index 000000000..6f47e9ec4
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/booking_tab.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/card.png b/base_hospital_management/static/description/assets/screenshots/card.png
new file mode 100755
index 000000000..cfee9dab7
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/card.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/card_print.png b/base_hospital_management/static/description/assets/screenshots/card_print.png
new file mode 100755
index 000000000..874ff95a0
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/card_print.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/consultation.png b/base_hospital_management/static/description/assets/screenshots/consultation.png
new file mode 100755
index 000000000..47f5ab91c
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/consultation.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/create_consultation.png b/base_hospital_management/static/description/assets/screenshots/create_consultation.png
new file mode 100755
index 000000000..26a3dc8aa
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/create_consultation.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/create_inpatient.png b/base_hospital_management/static/description/assets/screenshots/create_inpatient.png
new file mode 100755
index 000000000..9d08a8f4e
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/create_inpatient.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/create_invoice.png b/base_hospital_management/static/description/assets/screenshots/create_invoice.png
new file mode 100755
index 000000000..eb690e628
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/create_invoice.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/create_patient.png b/base_hospital_management/static/description/assets/screenshots/create_patient.png
new file mode 100755
index 000000000..3bddd9129
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/create_patient.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/create_sale.png b/base_hospital_management/static/description/assets/screenshots/create_sale.png
new file mode 100644
index 000000000..0939abb99
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/create_sale.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/create_test.png b/base_hospital_management/static/description/assets/screenshots/create_test.png
new file mode 100755
index 000000000..aa97a081d
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/create_test.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/create_test_wizard.png b/base_hospital_management/static/description/assets/screenshots/create_test_wizard.png
new file mode 100755
index 000000000..2467a286c
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/create_test_wizard.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/created_test.png b/base_hospital_management/static/description/assets/screenshots/created_test.png
new file mode 100755
index 000000000..2c54ed68d
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/created_test.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/doc_round.png b/base_hospital_management/static/description/assets/screenshots/doc_round.png
new file mode 100755
index 000000000..6f613f405
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/doc_round.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/doctor_db.png b/base_hospital_management/static/description/assets/screenshots/doctor_db.png
new file mode 100755
index 000000000..86c734cf1
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/doctor_db.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/doctor_surgery.png b/base_hospital_management/static/description/assets/screenshots/doctor_surgery.png
new file mode 100644
index 000000000..6a1d3233c
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/doctor_surgery.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/family.png b/base_hospital_management/static/description/assets/screenshots/family.png
new file mode 100755
index 000000000..bd4a0423f
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/family.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/hero.gif b/base_hospital_management/static/description/assets/screenshots/hero.gif
new file mode 100755
index 000000000..8b6faf249
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/hero.gif differ
diff --git a/base_hospital_management/static/description/assets/screenshots/inpatient.png b/base_hospital_management/static/description/assets/screenshots/inpatient.png
new file mode 100755
index 000000000..6f2a763c6
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/inpatient.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/invoice.png b/base_hospital_management/static/description/assets/screenshots/invoice.png
new file mode 100755
index 000000000..af1432b73
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/invoice.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/lab_assistant.png b/base_hospital_management/static/description/assets/screenshots/lab_assistant.png
new file mode 100755
index 000000000..d1e7754e4
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/lab_assistant.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/lab_dashboard.png b/base_hospital_management/static/description/assets/screenshots/lab_dashboard.png
new file mode 100755
index 000000000..20febe4b6
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/lab_dashboard.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/lab_test.png b/base_hospital_management/static/description/assets/screenshots/lab_test.png
new file mode 100755
index 000000000..e8f0db5f2
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/lab_test.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/lifestyle.png b/base_hospital_management/static/description/assets/screenshots/lifestyle.png
new file mode 100755
index 000000000..c5f9afd70
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/lifestyle.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/manager.png b/base_hospital_management/static/description/assets/screenshots/manager.png
new file mode 100755
index 000000000..ba3177db7
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/manager.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/medicines.png b/base_hospital_management/static/description/assets/screenshots/medicines.png
new file mode 100755
index 000000000..b63c0c9a9
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/medicines.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/nurse.png b/base_hospital_management/static/description/assets/screenshots/nurse.png
new file mode 100755
index 000000000..22171fd3b
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/nurse.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/op_line.png b/base_hospital_management/static/description/assets/screenshots/op_line.png
new file mode 100644
index 000000000..ba79e9466
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/op_line.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/orders.png b/base_hospital_management/static/description/assets/screenshots/orders.png
new file mode 100644
index 000000000..df784973e
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/orders.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/patient.png b/base_hospital_management/static/description/assets/screenshots/patient.png
new file mode 100755
index 000000000..a6f277649
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/patient.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/patient_history.png b/base_hospital_management/static/description/assets/screenshots/patient_history.png
new file mode 100755
index 000000000..937d4a2a0
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/patient_history.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/patient_rec.png b/base_hospital_management/static/description/assets/screenshots/patient_rec.png
new file mode 100644
index 000000000..c5f151021
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/patient_rec.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/patient_search.png b/base_hospital_management/static/description/assets/screenshots/patient_search.png
new file mode 100755
index 000000000..8aaffc56e
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/patient_search.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/patient_tab.png b/base_hospital_management/static/description/assets/screenshots/patient_tab.png
new file mode 100755
index 000000000..814227ffa
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/patient_tab.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/pha_db.png b/base_hospital_management/static/description/assets/screenshots/pha_db.png
new file mode 100755
index 000000000..652014102
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/pha_db.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/pha_home.png b/base_hospital_management/static/description/assets/screenshots/pha_home.png
new file mode 100755
index 000000000..7e6baf811
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/pha_home.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/pharmacist.png b/base_hospital_management/static/description/assets/screenshots/pharmacist.png
new file mode 100755
index 000000000..446a84257
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/pharmacist.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/portal.png b/base_hospital_management/static/description/assets/screenshots/portal.png
new file mode 100755
index 000000000..a4d958cd1
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/portal.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/prescription.png b/base_hospital_management/static/description/assets/screenshots/prescription.png
new file mode 100755
index 000000000..af77fdb61
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/prescription.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/print_prescription.png b/base_hospital_management/static/description/assets/screenshots/print_prescription.png
new file mode 100755
index 000000000..8d6d8013a
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/print_prescription.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/published_result.png b/base_hospital_management/static/description/assets/screenshots/published_result.png
new file mode 100755
index 000000000..cb54b0cba
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/published_result.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/rec_db.png b/base_hospital_management/static/description/assets/screenshots/rec_db.png
new file mode 100755
index 000000000..5b4c37b86
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/rec_db.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/receptionist.png b/base_hospital_management/static/description/assets/screenshots/receptionist.png
new file mode 100755
index 000000000..33009574d
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/receptionist.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/register_payment.png b/base_hospital_management/static/description/assets/screenshots/register_payment.png
new file mode 100755
index 000000000..80a0351ae
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/register_payment.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/result_line.png b/base_hospital_management/static/description/assets/screenshots/result_line.png
new file mode 100755
index 000000000..8aff4eec4
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/result_line.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/room.png b/base_hospital_management/static/description/assets/screenshots/room.png
new file mode 100755
index 000000000..9d5fa983a
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/room.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/room.png.png b/base_hospital_management/static/description/assets/screenshots/room.png.png
new file mode 100644
index 000000000..48f5cdac8
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/room.png.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/sale.png b/base_hospital_management/static/description/assets/screenshots/sale.png
new file mode 100755
index 000000000..f9ff6c10b
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/sale.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/shift.png b/base_hospital_management/static/description/assets/screenshots/shift.png
new file mode 100755
index 000000000..af07db671
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/shift.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/socio.png b/base_hospital_management/static/description/assets/screenshots/socio.png
new file mode 100755
index 000000000..50da0c2a6
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/socio.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/start_test.png b/base_hospital_management/static/description/assets/screenshots/start_test.png
new file mode 100755
index 000000000..85d4f3aa0
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/start_test.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/surgery.png b/base_hospital_management/static/description/assets/screenshots/surgery.png
new file mode 100755
index 000000000..490cd1fb3
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/surgery.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/surgery.png.png b/base_hospital_management/static/description/assets/screenshots/surgery.png.png
new file mode 100644
index 000000000..2fad09229
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/surgery.png.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/test2.png b/base_hospital_management/static/description/assets/screenshots/test2.png
new file mode 100755
index 000000000..7eb2e3e92
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/test2.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/test_create.png b/base_hospital_management/static/description/assets/screenshots/test_create.png
new file mode 100755
index 000000000..2a66b26df
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/test_create.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/test_details.png b/base_hospital_management/static/description/assets/screenshots/test_details.png
new file mode 100755
index 000000000..5745d5f8c
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/test_details.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/user_doctor.png b/base_hospital_management/static/description/assets/screenshots/user_doctor.png
new file mode 100755
index 000000000..5218b1d70
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/user_doctor.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/user_manager.png b/base_hospital_management/static/description/assets/screenshots/user_manager.png
new file mode 100755
index 000000000..3f1332d18
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/user_manager.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/vac_tab.png b/base_hospital_management/static/description/assets/screenshots/vac_tab.png
new file mode 100755
index 000000000..ac2901bdc
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/vac_tab.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/vac_wizard.png b/base_hospital_management/static/description/assets/screenshots/vac_wizard.png
new file mode 100755
index 000000000..d502a0e29
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/vac_wizard.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/vaccine.png b/base_hospital_management/static/description/assets/screenshots/vaccine.png
new file mode 100755
index 000000000..73f1acdd8
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/vaccine.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/view_inpatient.png b/base_hospital_management/static/description/assets/screenshots/view_inpatient.png
new file mode 100644
index 000000000..8b31f2bbe
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/view_inpatient.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/view_op.png b/base_hospital_management/static/description/assets/screenshots/view_op.png
new file mode 100644
index 000000000..c962b0a45
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/view_op.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/view_outpatient.png b/base_hospital_management/static/description/assets/screenshots/view_outpatient.png
new file mode 100644
index 000000000..5f3b89728
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/view_outpatient.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/view_patients.png b/base_hospital_management/static/description/assets/screenshots/view_patients.png
new file mode 100644
index 000000000..cef6b9676
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/view_patients.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/view_sale.png b/base_hospital_management/static/description/assets/screenshots/view_sale.png
new file mode 100644
index 000000000..9a43d779d
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/view_sale.png differ
diff --git a/base_hospital_management/static/description/assets/screenshots/website.png b/base_hospital_management/static/description/assets/screenshots/website.png
new file mode 100755
index 000000000..bde2cd77f
Binary files /dev/null and b/base_hospital_management/static/description/assets/screenshots/website.png differ
diff --git a/base_hospital_management/static/description/banner.jpg b/base_hospital_management/static/description/banner.jpg
new file mode 100755
index 000000000..e3cd0a1ea
Binary files /dev/null and b/base_hospital_management/static/description/banner.jpg differ
diff --git a/base_hospital_management/static/description/icon.png b/base_hospital_management/static/description/icon.png
new file mode 100755
index 000000000..1e63215f3
Binary files /dev/null and b/base_hospital_management/static/description/icon.png differ
diff --git a/base_hospital_management/static/description/index.html b/base_hospital_management/static/description/index.html
new file mode 100755
index 000000000..a49ebeaa3
--- /dev/null
+++ b/base_hospital_management/static/description/index.html
@@ -0,0 +1,1017 @@
+
+
+
+
+
+
+ Community
+
+
+ Enterprise
+
+
+
+
+
+
+
+
+
+ Hospital Management Odoo 16
+
+ This Module Helps to Manage Patients Records, Doctors Details, Lab Management , Employee Management etc.and there is Dashboard Created under the module that help to Analyze Services like Patient Details, Lab Details, Test Details Doctor's Allocations
+
+ The hospital management module can be used to handle the day-to-day
+ activities of the hospital. Managing patient scheduling, making patient
+ ID cards, creating patient lab test results, and adding doctors,
+ patients, prescriptions, vaccines, etc. are all made easier with the
+ help of this module. This app offers a different dashboards for
+ different users.
+
+
+
+
+
+
+
+
+
+
+ Features
+
+
+
+
+
+
+ Dashboard Services
+
+
+
+ Patient Management
+
+
+
+ Laboratory Management
+
+
+
+ Stock Management System
+
+
+
+ Blood Bank Management
+
+
+
+ Vaccination Management
+
+
+
+ Doctor's Allocation and Service Managment
+
+
+
+ Other Amenities
+
+
+
+ Medicine and Related Product Management
+
+
+
+ Other Amenities
+
+
+
+ Online Booking
+
+
+
+
+
+
+
+
+
+
+ Screenshots
+
+
+
+
+
+ Give the user access to the user group Manager.
+
+
+
+
+ Add Staff
+
+ Navigate to Staff menu under Configuration.
+ Add the Job
+ Position. Also add Consultation Type, Average Time for a Patient
+ and
+ Consultation Charge for
+ Doctors.
+
+
+
+
+
+ Add Medicine
+
+ Navigate to Medicine menu under Configuration and add new
+ medicines.
+
+
+
+
+
+ Add Vaccine
+
+ By navigating to Configuration -> Vaccine, a new vaccine can be
+ added.
+
+
+
+
+
+ Add Pharmacy
+
+ By navigating to Infrastructure > Pharmacy, a new pharmacy can be
+ added.
+
+
+
+
+
+ Add Room
+
+ By navigating to Infrastructure -> Room, a new room can be added.
+
+
+
+
+
+ Add Lab Test
+
+ By navigating to Laboratory -> Lab Test, a new lab test can be
+ added.
+
+
+
+
+
+ Add Doctor Allocation
+
+ By navigating to Appointment -> Allocation, a new allocation
+ can
+ be added and click CONFIRM.
+
+
+
+
+
+ Give the user access to the user group Doctor.
+
+
+
+
+ Doctor's Dashboard.
+
+
+
+
+ Consultation tab of Doctor's dashboard.
+
+ Click on Create button for adding new consultation.
+
+
+
+
+ Create new Consultation
+
+
+
+
+ Patient tab of Doctor's dashboard
+
+ There is a search option for searching a patient.
+
+
+
+
+
+ Inpatient tab of Doctor's dashboard
+
+ There is a Search option for searching an inpatient.
+
+
+
+
+
+ Surgery tab of Doctor's dashboard
+
+
+
+
+ Shift Allocation tab of Doctor's dashboard
+
+
+
+
+ Create new Patient
+
+ By navigating to Patient menu, a new patient can be added.
+
+
+
+
+
+ Click on Patient Card for generating the patient card.
+
+
+
+
+
+ Generated Patient Card.
+
+
+
+
+
+ Create Inpatient.
+
+
+ By navigating to Appointment -> Inpatient, a new Inpatient can be
+ added.
+
+
+
+
+
+ Give the user access to the user group Nurse.
+
+
+
+
+
+ Admit an Inpatient by clicking ADMIT button.
+
+
+
+
+ Click on PRESCRIPTION to print the prescription.
+
+
+
+
+ Printed Prescription
+
+
+
+
+ Click on CREATE TEST to create new test for an Inpatient.
+
+
+
+
+ Add the test details and click CONFIRM button
+
+
+
+
+ Create invoice by clicking the CREATE INVOICE button.
+
+
+
+
+ Give the user access to the user group Lab Assistant.
+
+
+
+
+ Lab Assistant's Dashboard
+
+
+
+
+ Click on the Create button under Tests to Confirm tab for
+ creating a new test.
+
+
+
+
+ Add lab test details and click CONFIRM button.
+
+
+
+
+ Click on any test.
+
+
+
+
+
+ Click on CONFIRM button.
+
+
+
+
+ The test will be added to Process Test. Click on any test
+ line.
+
+
+
+
+ Click the START button.
+
+
+
+
+ Click on result line.
+
+
+
+
+ Add test result.
+
+
+
+
+ Published tab will provide all published test results. It is
+ possible to download the result.
+
+
+
+
+ Vaccinations can be created by clicking the Create button under
+ Vaccination tab
+
+
+
+
+ Add vaccination details
+
+
+
+
+ Give the user access to the user group Pharmacist.
+
+
+
+
+ Pharmacist's Dashboard
+
+
+
+
+
+ Medicines tab of Pharmacist's dashboard
+
+
+
+
+ Vaccines tab of Pharmacist's dashboard
+
+
+
+
+ Orders tab of Pharmacist's dashboard
+
+
+
+
+ Patient search from Pharmacist's dashboard
+
+
+
+
+ Click any OP line
+
+
+
+
+ We can see the OP details here. Click CREATE SALE ORDER for
+ creating
+ sale order for medicines.
+
+
+
+
+ You can view the sales order in the "Orders" tab.
+
+
+
+
+ Give the user access to the user group Receptionist.
+
+
+
+
+ Receptionist's Dashboard
+
+
+
+
+ Patient Tab of Receptionist's Dashboard. It is possible to
+ create new Patients here.
+
+
+
+
+ Click VIEW PATIENTS button to view all patients.
+
+
+
+
+ All Patients.
+
+
+
+
+ Appointment tab of Receptionist's Dashboard. It is possible to
+ create Inpatient and Outpatient here.
+
+
+
+
+ Click VIEW OUTPATIENTS button to view all Outpatients.
+
+
+
+
+ Click VIEW INPATIENTS button to view all Inpatients.
+
+
+
+
+ Room/Ward tab of Receptionist's Dashboard. Here, it is possible
+ to search for a Room/Ward.