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) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
							 | 
						|
								#    Author: Subina P (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 = str(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 = 10
							 | 
						|
								
							 | 
						|
								    @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 data_list
							 | 
						|
								
							 |