I am having difficulties in setting up real-time communication for my Odoo app. I am still a newbie to javascript so I'm not sure if my javascript code is correct or not This is my odoo code:
class HospitalAppointment(models.Model):
_name = 'hospital.appointment'
_inherit = ['mail.thread', 'mail.activity.mixin']
_description = 'Hospital Appointment'
name = fields.Char(string='Order Ref', required=True, copy=False, readonly=True, index=True,
default=lambda self: _('New'))
patient_id = fields.Many2one('hospital.patient', string='Patient', required=True)
patient_age = fields.Integer(string='Age', related='patient_id.age')
patient_gender = fields.Selection([
('male', 'Male'),
('female', 'Female')], string='Gender', compute="_compute_patient_gender", store=False)
state = fields.Selection([
('draft', 'Draft'),
('confirm', 'Confirm'),
('done', 'Done'),
('cancel', 'Cancel')], string='Appointment Status', readonly=True, default='draft', tracking=True)
note = fields.Text(string='Appointment Note')
date_appointment = fields.Datetime(string='Date', required=True, tracking=True)
doctor_id = fields.Many2one('hospital.doctor', string='Doctor', required=True, tracking=True)
doctor_prescription = fields.Text(string='Prescription')
doctor_prescription_lines = fields.One2many('appointment.prescription.lines', 'appointment_id', required=True, string='Prescription Lines')
@api.model
def create(self, vals):
if vals.get('name', _('New')) == _('New'):
vals['name'] = self.env['ir.sequence'].next_by_code('hospital.appointment') or _('New')
doctor_app_count = self.env['hospital.appointment'].search_count(
[('doctor_id', '=', vals.get('doctor_id'))]) + 1
patient_app_count = self.env['hospital.appointment'].search_count(
[('patient_id', '=', vals.get('patient_id'))]) + 1
channel = (self._cr.dbname, 'appointment_notification', self.id)
message = {
'doctor_appointment_count': doctor_app_count,
'patient_appointment_count': patient_app_count
}
self.env['bus.bus'].sendone(channel, message)
print("Message sent!")
result = super(HospitalAppointment, self).create(vals)
return result
class Doctor(models.Model):
_name = 'hospital.doctor'
_inherit = ['mail.thread', 'mail.activity.mixin']
_description = 'Hospital Doctor Information'
reference = fields.Char(string='Order Reference', required=True, copy=False, readonly=True,
default=lambda self: _('New'))
name = fields.Char(string='Name', required=True, tracking=True)
age = fields.Integer(string='Age', tracking=True)
gender = fields.Selection([
('male', 'Male'),
('female', 'Female'),
('other', 'Other')
], required=True, default='male', tracking=True)
note = fields.Text(string='Description', tracking=True)
image = fields.Binary(string='Patient Image', tracking=True)
appointments = fields.One2many('hospital.appointment', 'doctor_id', string='Appointments')
doctor_appointment_count = fields.Integer(string='Appointments count', compute='_compute_appointment_count', store=False)
class HospitalPatient(models.Model):
_name = "hospital.patient"
_inherit = ['mail.thread', 'mail.activity.mixin']
_description = "Hospital Patient"
name = fields.Char(string='Name', required=True, tracking=True)
reference = fields.Char(string='Order Reference', required=True, copy=False, readonly=True,
default=lambda self: _('New'))
age = fields.Integer(string='Age', required=True, tracking=True)
gender = fields.Selection([
('male', 'Male'),
('female', 'Female')
], required=True, default='male', tracking=True)
note = fields.Text(string='Description', tracking=True)
state = fields.Selection([('draft', 'Draft'), ('confirmed', 'Confirm'), ('cancelled', 'Cancel')],
default='draft', string='Status', tracking=True)
responsible_id = fields.Many2one('res.users', ondelete='set null', string='Responsible', tracking=True)
appointments = fields.One2many('hospital.appointment', 'patient_id', string='Appointments')
patient_appointment_count = fields.Integer(string='Appointments', compute='_compute_appointment_count', store=False)
XML:
<record id="view_hospital_appointment_tree" model="ir.ui.view">
<field name="name">hospital.appointment.view_tree</field>
<field name="model">hospital.appointment</field>
<field name="arch" type="xml">
<tree string="view_hospital_appointment_tree" multi_edit="1">
<field name="name"/>
<field name="patient_id"/>
<field name="patient_age"/>
<field name="patient_gender"/>
<field name="state"/>
<field name="date_appointment"/>
<field name="doctor_id"/>
</tree>
</field>
</record>
<record id="view_hospital_appointment_form" model="ir.ui.view">
<field name="name">hospital.appointment.view_form</field>
<field name="model">hospital.appointment</field>
<field name="arch" type="xml">
<form string="view_hospital_appointment_form">
<header>
<button id="button_confirm" name="action_confirm" string="Confirm" states="draft"
confirm="Are you sure with your selection?" type="object" class="oe_highlight"/>
<button id="button_done" name="action_done" string="Mark as done" states="confirm"
confirm="Are you sure with your selection?" type="object" class="oe_highlight"/>
<button id="button_draft" name="action_draft" string="Set to Draft" states="cancel"
confirm="Are you sure with your selection?" type="object" class="oe_highlight"/>
<button id="button_cancel" name="action_cancel" string="Cancel" states="draft,confirm,done"
confirm="Are you sure with your selection?" type="object" />
<button name="action_url" string="Open URL" type="object" class="oe_highlight"/>
<field name="state" widget="statusbar"/>
</header>
<sheet>
<div class="oe_title">
<h1>
<field name="name" readonly="1"/>
</h1>
</div>
<group>
<group>
<field name="patient_id" options="{'no_create_edit': True}"/>
<field name="patient_age"/>
<field name="patient_gender"/>
</group>
<group>
<field name="date_appointment"/>
<field name="doctor_id" options="{'no_create': True}"/>
<field name="note"/>
</group>
</group>
<notebook>
<page string="Doctor's prescription">
<field name="doctor_prescription"/>
</page>
<page string="Medicines">
<field name="doctor_prescription_lines">
<tree editable="bottom">
<field name="name"/>
<field name="quantity"/>
</tree>
<form>
<group>
<field name="name"/>
</group>
</form>
</field>
</page>
</notebook>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field name="message_ids" widget="mail_thread"/>
<field name="activity_ids" widget="mail_activity"/>
</div>
</form>
</field>
</record>
<record id="action_hospital_appointment" model="ir.actions.act_window">
<field name="name">Appointments</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">hospital.appointment</field>
<field name="view_mode">tree,form</field>
<field name="context">{'default_note': 'New appointment created'}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Click to Create New Appointment
</p>
</field>
</record>
<record id="action_hospital_patient" model="ir.actions.act_window">
<field name="name">Patients</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">hospital.patient</field>
<field name="view_mode">tree,form,kanban</field>
<field name="context">{'default_note': 'New patient created'}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Click to Create New Patient
</p>
</field>
</record>
<record id="view_hospital_patient_tree" model="ir.ui.view">
<field name="name">hospital.patient.tree</field>
<field name="model">hospital.patient</field>
<field name="arch" type="xml">
<tree string="Hospital Patient">
<field name="name"/>
<field name="age"/>
<field name="gender"/>
<field name="note"/>
<field name="state"/>
<field name="patient_appointment_count"/>
<field name="responsible_id"/>
</tree>
</field>
</record>
<record id="action_hospital_doctors" model="ir.actions.act_window">
<field name="name">Doctors</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">hospital.doctor</field>
<field name="view_mode">tree,form,kanban</field>
<field name="context">{'default_note': 'New doctor created'}</field>
<field name="domain">[('age','>',0)]</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Click to Create New Doctors
</p>
</field>
</record>
<record id="view_hospital_doctors_tree" model="ir.ui.view">
<field name="name">hospital.doctor.tree</field>
<field name="model">hospital.doctor</field>
<field name="arch" type="xml">
<tree sample="1">
<field name="reference"/>
<field name="name"/>
<field name="age"/>
<field name="gender"/>
<field name="note"/>
<field name="doctor_appointment_count"/>
</tree>
</field>
</record>
views/assets_backend_inclusion.xml:
<odoo>
<template id="assets_backend" name="hospital assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/om_hospital/static/src/js/AppointmentCountChange.js"></script>
</xpath>
</template>
</odoo>
This is my javascript code for the client:
odoo.define('om_hospital.AppointmentCountChange', function (require) {
"use strict";
var webClient = require('web.WebClient');
var bus = require('bus.bus');
webClient.include({
start: function () {
this._super.apply(this, arguments);
bus.bus.on('appointment_notification', this, this._onNotification);
bus.start_polling();
},
_onNotification: function (notifications) {
var self = this;
_.each(notifications, function (notification) {
var channel = notification[0];
var message = notification[1];
if (channel[1] === 'appointment_notification') {
self.updateAppointmentCount(message.doctor_appointment_count, message.patient_appointment_count);
}
});
},
updateAppointmentCount: function (doctor_appointment_count, patient_appointment_count) {
var doctorAppointmentCountElement = document.querySelector('.doctor_appointment_count .o_field_widget');
var patientAppointmentCountElement = document.querySelector('.patient_appointment_count .o_field_widget');
if (doctorAppointmentCountElement && patientAppointmentCountElement) {
doctorAppointmentCountElement.textContent = doctor_appointment_count;
doctorAppointmentCountElement.innerHTML = doctor_appointment_count;
patientAppointmentCountElement.textContent = patient_appointment_count;
patientAppointmentCountElement.innerHTML = patient_appointment_count;
console.log(doctor_appointment_count);
console.log(patient_appointment_count);
}
}
});
});
This is my manifest.py:
{
'name' : 'Hospital Management',
'version' : '1.0',
'summary': 'Hospital management',
'sequence': 10,
'description': """Hospital Management Software""",
'category': 'Productivity',
'depends' : ['sale', 'mail', 'bus'],
'data': [
'security/ir.model.access.csv',
'data/data.xml',
'wizard/create_appointment_view.xml',
'views/appointments_view.xml',
'views/patients_view.xml',
'views/kids_view.xml',
'views/doctors_view.xml',
'views/sale.xml',
'views/assets_backend_inclusion.xml',
],
'demo': [],
'qweb': [],
'installable': True,
'application': True,
'auto_install': False,
'license': 'LGPL-3',
}
I opened a tab to view and create a new appointment and a tab to view the doctor tree view. When creating a new appointment, the doctor_appointment_count didn't update in real time, I had to reload the doctor_appointment tree view.
Although i added the bus module in the list of depends in manifest file, the console log still printed out a message: "Missing dependencies: "bus.bus""
I hope that I can get some support.