You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
220 lines
9.9 KiB
220 lines
9.9 KiB
# -*- coding: utf-8 -*-
|
|
################################################################################
|
|
#
|
|
# Cybrosys Technologies Pvt. Ltd.
|
|
#
|
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
|
|
# 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 <http://www.gnu.org/licenses/>.
|
|
#
|
|
################################################################################
|
|
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}
|
|
|