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.
		
		
		
		
		
			
		
			
				
					
					
						
							482 lines
						
					
					
						
							22 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							482 lines
						
					
					
						
							22 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/>. | |
| # | |
| ################################################################################ | |
| 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
 | |
| 
 |