├── .github └── FUNDING.yml ├── README.md └── om_hospital ├── README.rst ├── __init__.py ├── __manifest__.py ├── controllers ├── __init__.py ├── main.py └── portal.py ├── data ├── cron.xml ├── data.xml ├── mail_template.xml └── sequence.xml ├── models ├── __init__.py ├── appointment.py ├── doctor.py ├── lab.py ├── patient.py └── settings.py ├── reports ├── __init__.py ├── appointment.py ├── appointment.xml ├── patient_card.py ├── patient_card.xml ├── patient_card_xls.py ├── report.xml └── sale_report_inherit.xml ├── security ├── ir.model.access.csv └── security.xml ├── static └── description │ ├── banner.png │ ├── icon.png │ ├── index.html │ └── odoo_mates.png ├── views ├── appointment.xml ├── dashboard.xml ├── doctor.xml ├── lab.xml ├── partner_view.xml ├── patient.xml ├── portal_template.xml ├── sale_order.xml ├── settings.xml └── template.xml └── wizards ├── __init__.py ├── create_appointment.py └── create_appointment.xml /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: odoomates 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Odoo Development Tutorials 2 | 3 | Strating the odoo development for the beginners is not an easy task without proper guidance and without materials. 4 | 5 | So here we are contributing to the Odoo development Tutorials in our youtube channel, we will cover all the basics you need to become and Odoo Expert. Please subscribe the Youtube Channel and Support as. 6 | 7 | 8 | 1. Manifest File - https://www.youtube.com/watch?v=BDepk0LhVuI&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM 9 | 2. Creating New Model - https://www.youtube.com/watch?v=L6MxDR71_1k&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=2 10 | 3. Create new Menu and Action - https://www.youtube.com/watch?v=Tdg4YQowXyI&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=3 11 | 4. Defining Tree and Form Views - https://www.youtube.com/watch?v=3JMEroi4DIk&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=4 12 | 5. States and Workflows - https://www.youtube.com/watch?v=3PA7XAky8mA&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=22 13 | 6. Create PDF report - https://www.youtube.com/watch?v=SkKAXURqNfQ&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=24 14 | 7. Create Excel report - https://www.youtube.com/watch?v=cCyMy2kxxZs&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=45 15 | 8. Record Rules - https://www.youtube.com/watch?v=p8gj1dEfYUM&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=33 16 | 9. Access Rights - https://www.youtube.com/watch?v=W5ya521uTlo&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=5 17 | 10. Inherit and Add Field to Existing View: https://www.youtube.com/watch?v=z1Tx7EGkPy0&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=9 18 | 19 | 11. Search View: https://www.youtube.com/watch?v=hKigPT7GF7E&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=10 20 | 12. Define sequence for model:https://www.youtube.com/watch?v=ZfKzmfiqeg0&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=8 21 | 22 | 23 | For any help, feel free to Contact us @ odoomates@gmail.com 24 | -------------------------------------------------------------------------------- /om_hospital/README.rst: -------------------------------------------------------------------------------- 1 | ========================== 2 | Odoo Development Tutorials 3 | ========================== 4 | 5 | 6 | Odoo Development Tutorials For The Odoo Beginners and Freshers. Cover All the Basic topics of 7 | Odoo development. 8 | 9 | 10 | Installation 11 | ============ 12 | 13 | To install this module, you need to: 14 | 15 | Download the module and add it to your Odoo addons folder. Afterward, log on to 16 | your Odoo server and go to the Apps menu. Trigger the debug mode and update the 17 | list by clicking on the "Update Apps List" link. Now install the module by 18 | clicking on the install button. 19 | 20 | 21 | Configuration 22 | ============= 23 | 24 | There is Nothing to Configure 25 | 26 | 27 | Credits 28 | ======= 29 | 30 | Contributors 31 | ------------ 32 | 33 | * Odoo Mates 34 | 35 | 36 | Author & Maintainer 37 | ------------------- 38 | 39 | This module is maintained by the Odoo Mates 40 | -------------------------------------------------------------------------------- /om_hospital/__init__.py: -------------------------------------------------------------------------------- 1 | from . import controllers 2 | from . import models 3 | from . import wizards 4 | from . import reports 5 | -------------------------------------------------------------------------------- /om_hospital/__manifest__.py: -------------------------------------------------------------------------------- 1 | { 2 | 'name': 'Odoo Development Tutorials', 3 | 'version': '12.0.1.0.0', 4 | 'category': 'Extra Tools', 5 | 'summary': 'Odoo Development Tutorials For Beginners', 6 | 'sequence': '10', 7 | 'license': 'AGPL-3', 8 | 'author': 'Odoo Mates', 9 | 'maintainer': 'Odoo Mates', 10 | 'website': 'odoomates.com', 11 | 'live_test_url': 'https://www.youtube.com/watch?v=BDepk0LhVuI&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=1', 12 | 'depends': ['sale', 'mail', 'report_xlsx', 'board', 'kanban_draggable', 'website'], 13 | 'demo': [], 14 | 'data': [ 15 | 'security/security.xml', 16 | 'security/ir.model.access.csv', 17 | 'data/sequence.xml', 18 | 'data/data.xml', 19 | 'data/cron.xml', 20 | 'wizards/create_appointment.xml', 21 | 'views/patient.xml', 22 | 'views/appointment.xml', 23 | 'views/doctor.xml', 24 | 'views/lab.xml', 25 | 'views/sale_order.xml', 26 | 'views/partner_view.xml', 27 | 'views/template.xml', 28 | 'views/settings.xml', 29 | 'views/portal_template.xml', 30 | 'views/dashboard.xml', 31 | 'reports/patient_card.xml', 32 | 'reports/report.xml', 33 | 'reports/sale_report_inherit.xml', 34 | 'reports/appointment.xml', 35 | 'data/mail_template.xml', 36 | ], 37 | 'images': ['static/description/banner.png'], 38 | 'installable': True, 39 | 'application': True, 40 | 'auto_install': False, 41 | } 42 | # Video Explanation: https://www.youtube.com/watch?v=BDepk0LhVuI&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=1 43 | -------------------------------------------------------------------------------- /om_hospital/controllers/__init__.py: -------------------------------------------------------------------------------- 1 | from . import main 2 | from . import portal 3 | 4 | -------------------------------------------------------------------------------- /om_hospital/controllers/main.py: -------------------------------------------------------------------------------- 1 | from odoo import http 2 | from odoo.http import request 3 | from odoo.addons.website_sale.controllers.main import WebsiteSale 4 | 5 | 6 | class WebsiteSaleInherit(WebsiteSale): 7 | 8 | @http.route([ 9 | '''/shop''', 10 | '''/shop/page/''', 11 | '''/shop/category/''', 12 | '''/shop/category//page/''' 13 | ], type='http', auth="public", website=True) 14 | def shop(self, page=0, category=None, search='', ppg=False, **post): 15 | res = super(WebsiteSaleInherit, self).shop(page=0, category=None, search='', ppg=False, **post) 16 | print("Inherited Odoo Mates ....", res) 17 | return res 18 | 19 | 20 | class Hospital(http.Controller): 21 | 22 | # Sample Controller Created 23 | @http.route('/hospital/patient/', website=True, auth='user') 24 | def hospital_patient(self, **kw): 25 | # return "Thanks for watching" 26 | patients = request.env['hospital.patient'].sudo().search([]) 27 | return request.render("om_hospital.patients_page", { 28 | 'patients': patients 29 | }) 30 | 31 | @http.route('/update_patient', type='json', auth='user') 32 | def update_patient(self, **rec): 33 | if request.jsonrequest: 34 | if rec['id']: 35 | print("rec...", rec) 36 | patient = request.env['hospital.patient'].sudo().search([('id', '=', rec['id'])]) 37 | if patient: 38 | patient.sudo().write(rec) 39 | args = {'success': True, 'message': 'Patient Updated'} 40 | return args 41 | 42 | @http.route('/create_patient', type='json', auth='user') 43 | def create_patient(self, **rec): 44 | if request.jsonrequest: 45 | print("rec", rec) 46 | if rec['name']: 47 | vals = { 48 | 'patient_name': rec['name'], 49 | 'email_id': rec['email_id'] 50 | } 51 | new_patient = request.env['hospital.patient'].sudo().create(vals) 52 | print("New Patient Is", new_patient) 53 | args = {'success': True, 'message': 'Success', 'id': new_patient.id} 54 | return args 55 | 56 | @http.route('/get_patients', type='json', auth='user') 57 | def get_patients(self): 58 | print("Yes here entered") 59 | patients_rec = request.env['hospital.patient'].search([]) 60 | patients = [] 61 | for rec in patients_rec: 62 | vals = { 63 | 'id': rec.id, 64 | 'name': rec.patient_name, 65 | 'sequence': rec.name_seq, 66 | } 67 | patients.append(vals) 68 | print("Patient List--->", patients) 69 | data = {'status': 200, 'response': patients, 'message': 'Done All Patients Returned'} 70 | return data 71 | -------------------------------------------------------------------------------- /om_hospital/controllers/portal.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Part of Odoo. See LICENSE file for full copyright and licensing details. 3 | 4 | from odoo import http, _ 5 | from odoo.http import request 6 | from odoo.addons.portal.controllers.portal import CustomerPortal 7 | 8 | 9 | class CustomerPortal(CustomerPortal): 10 | 11 | def _prepare_portal_layout_values(self): 12 | values = super(CustomerPortal, self)._prepare_portal_layout_values() 13 | values['appointment_count'] = request.env['hospital.appointment'].sudo().search_count([]) 14 | return values 15 | 16 | @http.route(['/my/appointments'], type='http', auth="user", website=True) 17 | def portal_my_appointments(self, **kw): 18 | values = self._prepare_portal_layout_values() 19 | appointments = request.env['hospital.appointment'].sudo().search([]) 20 | values.update({ 21 | 'appointments': appointments, 22 | }) 23 | return request.render("om_hospital.portal_my_appointments", values) 24 | -------------------------------------------------------------------------------- /om_hospital/data/cron.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Check Patient Status 9 | 10 | ir.actions.server 11 | code 12 | model.test_cron_job() 13 | 1 14 | days 15 | -1 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /om_hospital/data/data.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Odoo Mates 23 | 25 24 | 9876543210 25 | fe_male 26 | Your Odoo Mate 27 | 28 | 29 | 30 | 31 | 32 | Subscribe the channel 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /om_hospital/data/mail_template.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Patient Card: Send by email 10 | 11 | ${object.user_id.email_formatted |safe} 12 | ${object.email_id} 13 | Patient Card (Ref ${object.name_seq}) 14 | 15 |
16 |

17 | Dear ${object.patient_name} 18 |

19 | Here is your patient card with reference ${object.name_seq} 20 |

21 | Age : ${object.patient_age} 22 | Contact Number : ${object.name} 23 |

24 | If you have queries feel free to ask. 25 |

26 |
27 |
28 | 29 | Patient Card_${(object.name_seq)} 30 |
31 |
32 | 33 |
34 | -------------------------------------------------------------------------------- /om_hospital/data/sequence.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Patient Sequence 10 | hospital.patient.sequence 11 | HP 12 | 3 13 | 14 | 15 | 16 | 17 | 18 | Appointment Sequence 19 | hospital.appointment 20 | HP 21 | 3 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /om_hospital/models/__init__.py: -------------------------------------------------------------------------------- 1 | from . import patient 2 | from . import appointment 3 | from . import doctor 4 | from . import lab 5 | from . import settings 6 | 7 | -------------------------------------------------------------------------------- /om_hospital/models/appointment.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import pytz 4 | from lxml import etree 5 | from odoo import models, fields, api, _ 6 | 7 | 8 | class HospitalAppointment(models.Model): 9 | _name = 'hospital.appointment' 10 | _description = 'Appointment' 11 | _inherit = ['mail.thread', 'mail.activity.mixin'] 12 | _order = "appointment_date desc" 13 | 14 | @api.model 15 | def fields_view_get(self, view_id=None, view_type='form', toolbar=False, 16 | submenu=False): 17 | result = super(HospitalAppointment, self).fields_view_get(view_id, 18 | view_type, 19 | toolbar=toolbar, 20 | submenu=submenu) 21 | 22 | doc = etree.XML(result['arch']) 23 | # print("doc", doc) 24 | # for elem in doc.xpath("//field[@name='appointment_date']"): 25 | # doc.remove(elem) 26 | # result['arch'] = doc 27 | return result 28 | 29 | # Deleting One2Many Lines From Code and Datetime Conversion , UTC -> Local 30 | # https://www.youtube.com/watch?v=ZxrDGTEU7B8&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=66 31 | # https://www.youtube.com/watch?v=2pOIxhE_xuY&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=59 32 | def delete_lines(self): 33 | for rec in self: 34 | user_tz = pytz.timezone(self.env.context.get('tz') or self.env.user.tz) 35 | time_in_timezone = pytz.utc.localize(rec.appointment_datetime).astimezone(user_tz) 36 | print("Time in UTC -->", rec.appointment_datetime) 37 | print("Time in Users Timezone -->", time_in_timezone) 38 | rec.appointment_lines = [(5, 0, 0)] 39 | 40 | # search, ref, browse, exists, create, write, copy, unlink , search_count , 41 | # name_get, name_search, default_get, display_name, 42 | # filtered, mapped, sorted, sudo, with_context, new, update,ensure_one, ids, search_read, user_has_group 43 | # ret_external_id, get_metadata, read, fields_get, read_group 44 | # get_formview_action, get_formview_id, user_has_group 45 | 46 | 47 | # Moving the State Of the Record To Confirm State in Button Click 48 | # How to Add States/Statusbar for Records in Odoo 49 | # https://www.youtube.com/watch?v=lPHWsw3Iclk&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=21 50 | def action_confirm(self): 51 | for rec in self: 52 | patient = self.env['hospital.patient'].search([('id', '=', 19)]) 53 | print("patient_name...", patient.patient_name) 54 | print("sequence...", patient.name_seq) 55 | print("Display Name...", patient.display_name) 56 | 57 | female_patients = self.env['hospital.patient'].search([('gender', '=', 'fe_male')]) 58 | filtered_female_patients = self.env['hospital.patient'].search([]).filtered(lambda s: s.gender == 'fe_male') 59 | print("female_patients....", female_patients) 60 | print("filtered_female_patients....", filtered_female_patients) 61 | mapped_patient_name = self.env['hospital.patient'].search([]).sorted(key='patient_age').mapped('patient_age') 62 | fg_patient_name = self.env['hospital.patient'].search([]).filtered(lambda s: s.gender == 'fe_male').sorted(key='patient_age', reverse=True).mapped('patient_age') 63 | print("mapped_patient_name...", mapped_patient_name) 64 | print("fg_patient_name...", fg_patient_name) 65 | 66 | product_category = self.env['product.category'].search([]).mapped('name') 67 | product_category_context = self.env['product.category'].with_context(lang='ar_SY').search([]).mapped('name') 68 | print("product_category...", product_category) 69 | print("product_category_context...", product_category_context) 70 | 71 | 72 | # max_sequence = self.env['hospital.patient'].search_read([], ['patient_name']) 73 | # print("female_patients", female_patients) 74 | # print("get_external_id", rec.get_external_id) 75 | # print("get_metadata", rec.get_metadata()) 76 | 77 | 78 | # print(female_patients) 79 | # odoo search method 80 | # patients = self.env['hospital.patient'].search([]) 81 | # print("patients...", patients) 82 | # search with and 83 | # female_patients = self.env['hospital.patient'].search([('gender', '=', 'fe_male'), 84 | # ('patient_age', '>=', 30)]) 85 | # print("female_patients age above 30...", female_patients) 86 | 87 | # search with OR 88 | # female_patients_or = self.env['hospital.patient'].search(['|', ('gender', '=', 'fe_male'), 89 | # ('patient_age', '>=', 30)]) 90 | 91 | # print("female_patients_or...", female_patients_or) 92 | 93 | # male_patients = self.env['hospital.patient'].search([('gender', '=', 'male')]) 94 | # print("male_patients....", male_patients) 95 | 96 | 97 | # odoo search count 98 | # patient_count = self.env['hospital.patient'].search_count([]) 99 | # print("patient_count...", patient_count) 100 | # female_patients_or = self.env['hospital.patient'].search_count(['|', ('gender', '=', 'fe_male'), 101 | # ('patient_age', '>=', 30)]) 102 | # print("female_patients_or count", female_patients_or) 103 | 104 | 105 | 106 | # Ref in Odoo 107 | 108 | # om_patient = self.env.ref('om_hospital.patient_xyz') 109 | # print("om_patient", om_patient.id) 110 | 111 | # Browse 112 | # browse_result = self.env['hospital.patient'].browse(12) 113 | # browse_result = self.env['hospital.patient'].search([('id', '=', 200)]) 114 | 115 | # print("browse_result....", browse_result) 116 | #Exists 117 | # if browse_result.exists(): 118 | # print("Existing") 119 | # else: 120 | # print("NOOOOOOOOOOOOOOOOOOOOOOOOOO") 121 | # vals = { 122 | # 'patient_name': 'Odoo ERP', 123 | # 'email_id': 'odoomates@gmail.com', 124 | # 'name': 55555555555555555 125 | # } 126 | # created_record = self.env['hospital.patient'].create(vals) 127 | # print("created_record", created_record, created_record.id) 128 | 129 | # record_to_update = self.env['hospital.patient'].browse(15) 130 | # if record_to_update.exists(): 131 | # vals = { 132 | # 'email_id': 'newemail@gmail.com', 133 | # 'name': 777777777777777777777, 134 | # 'notes': 'Please like an subscribe the channel' 135 | # } 136 | # record_to_update.write(vals) 137 | 138 | # record_to_copy = self.env['hospital.patient'].browse(14) 139 | # record_to_copy.copy() 140 | 141 | # record_to_copy = self.env['hospital.patient'].browse(17) 142 | # record_to_copy.unlink() 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | # rec.state = 'confirm' 151 | 152 | def action_done(self): 153 | for rec in self: 154 | rec.state = 'done' 155 | 156 | # Overriding the Create Method in Odoo 157 | # https://www.youtube.com/watch?v=ZfKzmfiqeg0&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=8 158 | @api.model 159 | def create(self, vals): 160 | # overriding the create method to add the sequence 161 | if vals.get('name', _('New')) == _('New'): 162 | vals['name'] = self.env['ir.sequence'].next_by_code('hospital.appointment') or _('New') 163 | result = super(HospitalAppointment, self).create(vals) 164 | return result 165 | 166 | # How to Override the Write Method in Odoo 167 | # https://www.youtube.com/watch?v=v8sXFUi1SH4&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=50 168 | @api.multi 169 | def write(self, vals): 170 | # overriding the write method of appointment model 171 | res = super(HospitalAppointment, self).write(vals) 172 | print("Test write function") 173 | # do as per the need 174 | return res 175 | 176 | # Give Domain For A field dynamically in Onchange 177 | # How To Give Domain For A Field Based On Another Field 178 | # https://www.youtube.com/watch?v=IpXXYCsK2ow&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=65 179 | @api.onchange('partner_id') 180 | def onchange_partner_id(self): 181 | for rec in self: 182 | return {'domain': {'order_id': [('partner_id', '=', rec.partner_id.id)]}} 183 | 184 | @api.model 185 | def default_get(self, fields): 186 | res = super(HospitalAppointment, self).default_get(fields) 187 | print("test......") 188 | res['patient_id'] = 1 189 | res['notes'] = 'please like the video' 190 | return res 191 | 192 | name = fields.Char(string='Appointment ID', required=True, copy=False, readonly=True, 193 | index=True, default=lambda self: _('New')) 194 | patient_id = fields.Many2one('hospital.patient', string='Patient', required=True) 195 | doctor_id = fields.Many2one('hospital.doctor', string='Doctor') 196 | patient_age = fields.Integer('Age', related='patient_id.patient_age') 197 | notes = fields.Text(string="Registration Note") 198 | doctor_note = fields.Text(string="Note", track_visibility='onchange') 199 | # How to Create One2Many Field 200 | # https://www.youtube.com/watch?v=_O_tNBdg3HQ&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=34 201 | appointment_lines = fields.One2many('hospital.appointment.lines', 'appointment_id', string='Appointment Lines') 202 | pharmacy_note = fields.Text(string="Note", track_visibility='always') 203 | appointment_date = fields.Date(string='Date') 204 | appointment_datetime = fields.Datetime(string='Date Time') 205 | partner_id = fields.Many2one('res.partner', string="Customer") 206 | order_id = fields.Many2one('sale.order', string="Sale Order") 207 | amount = fields.Float(string="Total Amount") 208 | state = fields.Selection([ 209 | ('draft', 'Draft'), 210 | ('confirm', 'Confirm'), 211 | ('done', 'Done'), 212 | ('cancel', 'Cancelled'), 213 | ], string='Status', readonly=True, default='draft') 214 | 215 | 216 | class HospitalAppointmentLines(models.Model): 217 | _name = 'hospital.appointment.lines' 218 | _description = 'Appointment Lines' 219 | 220 | product_id = fields.Many2one('product.product', string='Medicine') 221 | product_qty = fields.Integer(string="Quantity") 222 | appointment_id = fields.Many2one('hospital.appointment', string='Appointment ID') 223 | display_type = fields.Selection([ 224 | ('line_section', "Section"), 225 | ('line_note', "Note")], default=False, help="Technical field for UX purpose.") 226 | -------------------------------------------------------------------------------- /om_hospital/models/doctor.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from odoo import models, fields 4 | 5 | 6 | # Creating Model/Table to Store Doctor Details 7 | # https://www.youtube.com/watch?v=L6MxDR71_1k&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=2 8 | class HospitalDoctor(models.Model): 9 | _name = 'hospital.doctor' 10 | _inherits = {'hospital.patient': 'related_patient_id'} 11 | _description = 'Doctor Record' 12 | 13 | name = fields.Char(string="Name", required=True) 14 | gender = fields.Selection([ 15 | ('male', 'Male'), 16 | ('fe_male', 'Female'), 17 | ], default='male', string="Gender") 18 | user_id = fields.Many2one('res.users', string='Related User') 19 | patient_id = fields.Many2one('hospital.patient', string='Related Patient') 20 | related_patient_id = fields.Many2one('hospital.patient', string='Related Patient ID') 21 | -------------------------------------------------------------------------------- /om_hospital/models/lab.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from odoo import models, fields 4 | 5 | 6 | # Creating New Model/ Database Table 7 | # https://www.youtube.com/watch?v=L6MxDR71_1k&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=2 8 | class HospitalLab(models.Model): 9 | _name = 'hospital.lab' 10 | _description = 'Hospital Laboratory' 11 | 12 | name = fields.Char(string="Name", required=True) 13 | user_id = fields.Many2one('res.users', string='Responsible') 14 | -------------------------------------------------------------------------------- /om_hospital/models/patient.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from odoo import models, fields, api, _ 4 | from odoo.exceptions import ValidationError 5 | 6 | 7 | class ResPartners(models.Model): 8 | _inherit = 'res.partner' 9 | 10 | # How to OverRide Create Method Of a Model 11 | # https://www.youtube.com/watch?v=AS08H3G9x1U&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=26 12 | @api.model 13 | def create(self, vals_list): 14 | res = super(ResPartners, self).create(vals_list) 15 | print("yes working") 16 | # do the custom coding here 17 | return res 18 | 19 | 20 | # Inheriting the Sale Order Model and Adding New Field 21 | # https://www.youtube.com/watch?v=z1Tx7EGkPy0&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=9 22 | class SaleOrderInherit(models.Model): 23 | _inherit = 'sale.order' 24 | 25 | patient_name = fields.Char(string='Patient Name') 26 | 27 | 28 | class ResPartner(models.Model): 29 | _inherit = 'res.partner' 30 | 31 | company_type = fields.Selection(selection_add=[('om', 'Odoo Mates'), ('odoodev', 'Odoo Dev')]) 32 | 33 | 34 | # How to Create New Models : https://www.youtube.com/watch?v=L6MxDR71_1k&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=2 35 | class HospitalPatient(models.Model): 36 | _name = 'hospital.patient' 37 | _inherit = ['mail.thread', 'mail.activity.mixin'] 38 | _description = 'Patient Record' 39 | _rec_name = 'patient_name' 40 | 41 | # Print PDF Report From Button Click in Form 42 | # https://www.youtube.com/watch?v=Dc8GDj7ygsI&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=67 43 | @api.multi 44 | def print_report(self): 45 | return self.env.ref('om_hospital.report_patient_card').report_action(self) 46 | 47 | # Function which is executed using the Cron Job/ Scheduled Action 48 | # https://www.youtube.com/watch?v=_P_AVSNr6uU&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=52 49 | @api.model 50 | def test_cron_job(self): 51 | print("Abcd")# print will get printed in the log of pycharm 52 | #code accordingly to execute the cron 53 | 54 | # https://www.youtube.com/watch?v=-1r3WSwtqxQ 55 | @api.multi 56 | def name_get(self): 57 | # name get function for the model executes automatically 58 | res = [] 59 | for rec in self: 60 | res.append((rec.id, '%s - %s' % (rec.patient_name, rec.name_seq))) 61 | return res 62 | 63 | @api.model 64 | def _name_search(self, name='', args=None, operator='ilike', limit=100): 65 | if args is None: 66 | args = [] 67 | domain = args + ['|', ('name_seq', operator, name), ('patient_name', operator, name)] 68 | return super(HospitalPatient, self).search(domain, limit=limit).name_get() 69 | 70 | # Add Constrains For a Field 71 | # https://www.youtube.com/watch?v=ijS-N1CdiWU&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=14 72 | @api.constrains('identification_id') 73 | def check_identification_id(self): 74 | for rec in self: 75 | if len(rec.identification_id) != 11: 76 | raise ValidationError(_('Must be 11 Characters')) 77 | 78 | # Action For Smart Button 79 | # https://www.youtube.com/watch?v=I93Lr-bprIc&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=19 80 | @api.multi 81 | def open_patient_appointments(self): 82 | return { 83 | 'name': _('Appointments'), 84 | 'domain': [('patient_id', '=', self.id)], 85 | 'view_type': 'form', 86 | 'res_model': 'hospital.appointment', 87 | 'view_id': False, 88 | 'view_mode': 'tree,form', 89 | 'type': 'ir.actions.act_window', 90 | } 91 | 92 | def get_appointment_count(self): 93 | count = self.env['hospital.appointment'].search_count([('patient_id', '=', self.id)]) 94 | self.appointment_count = count 95 | 96 | # How to Write Onchange Functions 97 | # https://www.youtube.com/watch?v=qyRhjyp1MeE&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=39 98 | @api.onchange('doctor_id') 99 | def set_doctor_gender(self): 100 | for rec in self: 101 | if rec.doctor_id: 102 | rec.doctor_gender = rec.doctor_id.gender 103 | 104 | # Sending Email in Button Click 105 | # https://www.youtube.com/watch?v=CZVRmtv6re0&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=44 106 | def action_send_card(self): 107 | # sending the patient report to patient via email 108 | template_id = self.env.ref('om_hospital.patient_card_email_template').id 109 | template = self.env['mail.template'].browse(template_id) 110 | template.send_mail(self.id, force_send=True) 111 | 112 | # compute function in Odoo 113 | # https://www.youtube.com/watch?v=Mg80GxrKDOc&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=11 114 | @api.depends('patient_name') 115 | def _compute_upper_name(self): 116 | for rec in self: 117 | rec.patient_name_upper = rec.patient_name.upper() if rec.patient_name else False 118 | 119 | @api.depends('patient_age') 120 | def set_age_group(self): 121 | for rec in self: 122 | if rec.patient_age: 123 | if rec.patient_age < 18: 124 | rec.age_group = 'minor' 125 | else: 126 | rec.age_group = 'major' 127 | 128 | # Making compute field editable using inverse function 129 | # https://www.youtube.com/watch?v=NEr6hUTrn84&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=47 130 | def _inverse_upper_name(self): 131 | for rec in self: 132 | rec.patient_name = rec.patient_name_upper.lower() if rec.patient_name_upper else False 133 | 134 | # Overriding the create method to assign sequence for the record 135 | # https://www.youtube.com/watch?v=ZfKzmfiqeg0&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=8 136 | @api.model 137 | def create(self, vals): 138 | if vals.get('name_seq', _('New')) == _('New'): 139 | vals['name_seq'] = self.env['ir.sequence'].next_by_code('hospital.patient.sequence') or _('New') 140 | result = super(HospitalPatient, self).create(vals) 141 | return result 142 | 143 | xml_id = fields.Char('External ID', compute='_compute_xml_id',) 144 | 145 | def _compute_xml_id(self): 146 | res = self.get_external_id() 147 | for rec in self: 148 | rec.xml_id = res.get(rec.id) 149 | 150 | name = fields.Char(string="Contact Number") 151 | name_seq = fields.Char(string='Patient ID', required=True, copy=False, readonly=True, 152 | index=True, default=lambda self: _('New')) 153 | gender = fields.Selection([ 154 | ('male', 'Male'), 155 | ('fe_male', 'Female'), 156 | ], default='male', string="Gender") 157 | age_group = fields.Selection([ 158 | ('major', 'Major'), 159 | ('minor', 'Minor'), 160 | ], string="Age Group", compute='set_age_group', store=True) 161 | patient_name = fields.Char(string='Name', required=True, track_visibility="always") 162 | patient_age = fields.Integer('Age', track_visibility="always", group_operator=False) 163 | patient_age2 = fields.Float(string="Age2") 164 | notes = fields.Text(string="Registration Note") 165 | image = fields.Binary(string="Image", attachment=True) 166 | appointment_count = fields.Integer(string='Appointment', compute='get_appointment_count') 167 | active = fields.Boolean("Active", default=True) 168 | doctor_id = fields.Many2one('hospital.doctor', string="Doctor") 169 | email_id = fields.Char(string="Email") 170 | user_id = fields.Many2one('res.users', string="PRO") 171 | doctor_gender = fields.Selection([ 172 | ('male', 'Male'), 173 | ('fe_male', 'Female'), 174 | ], string="Doctor Gender") 175 | patient_name_upper = fields.Char(compute='_compute_upper_name', inverse='_inverse_upper_name') 176 | company_id = fields.Many2one('res.company', required=True, default=lambda self: self.env.user.company_id) 177 | -------------------------------------------------------------------------------- /om_hospital/models/settings.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from odoo import models, fields, api, _ 3 | from ast import literal_eval 4 | 5 | 6 | class HospitalSettings(models.TransientModel): 7 | _inherit = 'res.config.settings' 8 | 9 | note = fields.Char(string='Default Note') 10 | module_crm = fields.Boolean(string='CRM') 11 | product_ids = fields.Many2many('product.product', string='Medicines') 12 | 13 | def set_values(self): 14 | res = super(HospitalSettings, self).set_values() 15 | self.env['ir.config_parameter'].set_param('om_hospital.note', self.note) 16 | print("test", self.product_ids.ids) 17 | self.env['ir.config_parameter'].set_param('om_hospital.product_ids', self.product_ids.ids) 18 | return res 19 | 20 | @api.model 21 | def get_values(self): 22 | res = super(HospitalSettings, self).get_values() 23 | ICPSudo = self.env['ir.config_parameter'].sudo() 24 | notes = ICPSudo.get_param('om_hospital.note') 25 | product_ids = self.env['ir.config_parameter'].sudo().get_param('om_hospital.product_ids') 26 | if product_ids: 27 | print("product_ids", type(literal_eval(product_ids))) 28 | res.update( 29 | note=notes, 30 | product_ids=[(6, 0, literal_eval(product_ids))], 31 | ) 32 | return res 33 | 34 | -------------------------------------------------------------------------------- /om_hospital/reports/__init__.py: -------------------------------------------------------------------------------- 1 | from . import patient_card_xls 2 | from . import patient_card 3 | from . import appointment 4 | 5 | -------------------------------------------------------------------------------- /om_hospital/reports/appointment.py: -------------------------------------------------------------------------------- 1 | from odoo import api, models, _ 2 | 3 | 4 | class AppointmentReport(models.AbstractModel): 5 | _name = 'report.om_hospital.appointment_report' 6 | _description = 'Appointment Report' 7 | 8 | @api.model 9 | def _get_report_values(self, docids, data=None): 10 | if data['form']['patient_id']: 11 | appointments = self.env['hospital.appointment'].search([('patient_id', '=', data['form']['patient_id'][0])]) 12 | else: 13 | appointments = self.env['hospital.appointment'].search([]) 14 | # appointment_list = [] 15 | # for app in appointments: 16 | # vals = { 17 | # 'name': app.name, 18 | # 'notes': app.notes, 19 | # 'appointment_date': app.appointment_date 20 | # } 21 | # appointment_list.append(vals) 22 | print("data", data) 23 | return { 24 | 'doc_model': 'hospital.patient', 25 | 'appointments': appointments, 26 | 'data': data['form'] 27 | } 28 | -------------------------------------------------------------------------------- /om_hospital/reports/appointment.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /om_hospital/reports/patient_card.py: -------------------------------------------------------------------------------- 1 | from odoo import api, models, _ 2 | 3 | 4 | # How To Call A Python Function While Printing PDF Report in Odoo 5 | # https://www.youtube.com/watch?v=JGWc1KjyIBk&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=62 6 | class PatientCardReport(models.AbstractModel): 7 | _name = 'report.om_hospital.report_patient' 8 | _description = 'Patient card Report' 9 | 10 | @api.model 11 | def _get_report_values(self, docids, data=None): 12 | docs = self.env['hospital.patient'].browse(docids[0]) 13 | appointments = self.env['hospital.appointment'].search([('patient_id', '=', docids[0])]) 14 | appointment_list = [] 15 | return { 16 | 'doc_model': 'hospital.patient', 17 | 'docs': docs, 18 | 'appointment_list': appointment_list, 19 | } 20 | -------------------------------------------------------------------------------- /om_hospital/reports/patient_card.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 85 | 86 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /om_hospital/reports/patient_card_xls.py: -------------------------------------------------------------------------------- 1 | from odoo import models 2 | 3 | 4 | # Creating Excel Report 5 | # https://www.youtube.com/watch?v=cCyMy2kxxZs&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=46 6 | class PatientCardXLS(models.AbstractModel): 7 | _name = 'report.om_hospital.report_patient_xls' 8 | _inherit = 'report.report_xlsx.abstract' 9 | 10 | def generate_xlsx_report(self, workbook, data, line): 11 | c = 0 12 | for lines in line: 13 | c += 1 14 | format1 = workbook.add_format({'font_size': 14, 'align': 'vcenter', 'bold': True}) 15 | format2 = workbook.add_format({'font_size': 10, 'align': 'vcenter', }) 16 | sheet = workbook.add_worksheet('Patient Card %s' % (c)) 17 | sheet.set_column(3, 3, 50) 18 | sheet.set_column(2, 2, 30) 19 | sheet.write(2, 2, 'Name', format1) 20 | sheet.write(2, 3, lines.patient_name, format2) 21 | sheet.write(3, 2, 'Age', format1) 22 | sheet.write(3, 3, lines.patient_age, format2) 23 | -------------------------------------------------------------------------------- /om_hospital/reports/report.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | 19 | 20 | 27 | 28 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /om_hospital/reports/sale_report_inherit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /om_hospital/security/ir.model.access.csv: -------------------------------------------------------------------------------- 1 | id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink 2 | access_hospital_lab,access.hospital.lab,om_hospital.model_hospital_lab,om_hospital.group_hospital_lab,1,1,1,1 3 | access_hospital_patient,access.hospital.patient,model_hospital_patient,,1,1,1,1 4 | access_hospital_appointment,access.hospital.appointment,model_hospital_appointment,,1,1,1,1 5 | access_hospital_appointment_lines,access.hospital.appointment.lines,model_hospital_appointment_lines,,1,1,1,1 6 | access_hospital_doctor,access.hospital.doctor,model_hospital_doctor,,1,1,1,1 7 | -------------------------------------------------------------------------------- /om_hospital/security/security.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Hospital Management 8 | Category For Hospital 9 | 45 10 | 11 | 12 | 13 | Doctor 14 | 15 | 16 | 17 | 18 | Manager 19 | 20 | 21 | 22 | 23 | 24 | 25 | Lab Assistant User 26 | 27 | 28 | 29 | 30 | Lab Assistant Manager 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | See His Lab Only 39 | 40 | [('user_id','=',user.id)] 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | See All Lab 50 | 51 | [(1, '=', 1)] 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | See only His Patient 62 | 63 | [('doctor_id.user_id','=',user.id)] 64 | 65 | 66 | 67 | 68 | See All Patient 69 | 70 | [] 71 | 72 | 73 | 74 | 75 | Patient Multi Company Rule 76 | 77 | 78 | ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /om_hospital/static/description/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/odoomates/Development-Tutorials/96b521d020b4fca98cc368b06c828fffcb26e604/om_hospital/static/description/banner.png -------------------------------------------------------------------------------- /om_hospital/static/description/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/odoomates/Development-Tutorials/96b521d020b4fca98cc368b06c828fffcb26e604/om_hospital/static/description/icon.png -------------------------------------------------------------------------------- /om_hospital/static/description/index.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Odoo Development Tutorials

4 |
5 |
6 | 7 |
8 |
9 |

Become a Odoo Developer Easily. Almost all the 10 | basic topics covered, Configure Odoo and Pycharm, Create Your First Module. How to Create New Models, Define 11 | New Menu, Action and Different Views. Basics of Creating PDF Report and Excel Reports. Statusbar, State and 12 | WorkFlows, Wizard etc

13 |
14 |
15 | 16 |
17 | 25 |
26 | 27 | 28 |
29 |
30 |
31 |
32 |
33 | 34 |
35 |

If you have any queries or doubt just contact us:


36 |

Email: odoomates@gmail.com

37 |
38 |
39 |

40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 |

53 |
54 |
55 |
56 |
57 |
58 |
59 | -------------------------------------------------------------------------------- /om_hospital/static/description/odoo_mates.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/odoomates/Development-Tutorials/96b521d020b4fca98cc368b06c828fffcb26e604/om_hospital/static/description/odoo_mates.png -------------------------------------------------------------------------------- /om_hospital/views/appointment.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | hospital.appointment.tree 10 | hospital.appointment 11 | 12 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | hospital.appointment.pivot 25 | hospital.appointment 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | hospital.appointment.calendar 36 | hospital.appointment 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | hospital.appointment.graph 47 | hospital.appointment 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | hospital.appointment.form 59 | hospital.appointment 60 | 61 |
62 |
63 |
69 | 70 |
71 |

72 | 73 |

74 |
75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 |
117 |
118 | 119 | 120 | 121 |
122 | 123 |
124 |
125 | 126 | 127 | 128 | 129 | 130 | 131 | Appointments 132 | ir.actions.act_window 133 | hospital.appointment 134 | form 135 | calendar,tree,form,pivot,graph 136 | {} 137 | 138 |

139 | Create your First Appointment ! 140 |

141 |
142 |
143 | 144 | 146 | 147 | 148 | 149 | 150 | 151 | Appointments 152 | ir.actions.act_window 153 | hospital.appointment 154 | [('patient_id', '=', active_id)] 155 | form 156 | tree,form 157 | 158 | 159 | 160 | 161 |
162 | -------------------------------------------------------------------------------- /om_hospital/views/dashboard.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Patient Appointments 6 | hospital.appointment 7 | graph 8 | 9 | 10 | 11 | 12 | Book Appointments 13 | hospital.appointment 14 | calendar 15 | 16 | 17 | 18 | 19 | Patients 20 | hospital.patient 21 | tree,form 22 | 23 | 24 | 25 | Dashboard Form 26 | board.board 27 | form 28 | 29 |
30 | 31 | 32 | 35 | 38 | 39 | 40 | 43 | 44 | 45 |
46 |
47 |
48 | 49 | 50 | Dashboard 51 | board.board 52 | form 53 | menu 54 | 55 | 56 | 57 | 63 | 64 |
-------------------------------------------------------------------------------- /om_hospital/views/doctor.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 14 | 15 | hospital.doctor.tree 16 | hospital.doctor 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | hospital.doctor.form 28 | hospital.doctor 29 | 30 | 31 |
32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 |
43 |
44 | 45 | 46 | 47 | hospital.doctor.form 48 | hospital.doctor 49 | 50 | 51 |
52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
64 |
65 |
66 | 67 | 68 | 69 | Doctor 70 | ir.actions.act_window 71 | hospital.doctor 72 | form 73 | tree,form 74 | {} 75 | 80 | 81 |

82 | Create your First Doctor ! 83 |

84 |
85 |
86 | 87 | 88 | 89 | 90 |
91 | -------------------------------------------------------------------------------- /om_hospital/views/lab.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | hospital.lab.tree 6 | hospital.lab 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | hospital.lab.form 17 | hospital.lab 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
32 |
33 | 34 | 35 | Lab 36 | ir.actions.act_window 37 | hospital.lab 38 | form 39 | tree,form 40 | {} 41 | 42 |

43 | Create your First Lab ! 44 |

45 |
46 |
47 | 48 | 50 | 51 |
52 | -------------------------------------------------------------------------------- /om_hospital/views/partner_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | res.partner.inherit 6 | res.partner 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /om_hospital/views/patient.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Appointments 8 | ir.actions.act_window 9 | hospital.appointment 10 | form 11 | tree,form 12 | [('patient_id','=',active_id)] 13 | 14 |

15 | Create your First Appointment ! 16 |

17 |
18 |
19 | 20 | 21 | 22 | hospital.patient.tree 23 | hospital.patient 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | hospital.patient.form 39 | hospital.patient 40 | 41 |
42 |
43 |
49 | 50 |
51 | 54 | 57 |
58 | 59 |
60 |

61 | 62 |

63 |
64 | 65 | 66 | 67 | 68 | 69 | 70 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 |
88 |
89 | 90 | 91 | 92 |
93 |
94 |
95 |
96 | 97 | 98 | hospital.patient.kanban 99 | hospital.patient 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 |
110 | 111 |
113 | 114 | 115 | Avatar 116 | 117 |
118 | 119 |
120 |
    121 |
  • Age :
  • 122 |
  • Doctor :
  • 123 |
  • Email :
  • 124 |
125 |
126 |
127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | hospital.patient.search 139 | hospital.patient 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | Patients 161 | ir.actions.act_window 162 | hospital.patient 163 | form 164 | kanban,tree,form 165 | {"search_default_female":1} 166 | 167 |

168 | Create your First Patient ! 169 |

170 |
171 |
172 | 173 | 174 | 175 | 176 | 178 | 179 | 180 | -------------------------------------------------------------------------------- /om_hospital/views/portal_template.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 42 | 43 | -------------------------------------------------------------------------------- /om_hospital/views/sale_order.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | sale.order.inherit 7 | sale.order 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | Appointment 18 | 19 | 20 | 21 | 22 | New Quotation 23 | 100 24 | 25 | 26 | 27 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /om_hospital/views/settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | res.config.settings.view.form.inherit.sale 6 | res.config.settings 7 | 8 | 9 | 10 | 11 |
12 |

Hospital Management

13 | 14 |
15 |
16 |
19 |
20 |
21 | 22 |
23 |
24 |
27 |
28 |
29 | 30 |
31 |
32 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | 42 | 43 | Hospital Settings 44 | ir.actions.act_window 45 | res.config.settings 46 | 47 | form 48 | inline 49 | {'module' : 'om_hospital'} 50 | 51 | 52 | 56 | 57 | 62 | 63 |
64 | -------------------------------------------------------------------------------- /om_hospital/views/template.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /om_hospital/wizards/__init__.py: -------------------------------------------------------------------------------- 1 | from . import create_appointment 2 | 3 | -------------------------------------------------------------------------------- /om_hospital/wizards/create_appointment.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from odoo import models, fields 4 | 5 | 6 | class CreateAppointment(models.TransientModel): 7 | _name = 'create.appointment' 8 | _description = 'Create Appointment Wizard' 9 | 10 | patient_id = fields.Many2one('hospital.patient', string="Patient") 11 | appointment_date = fields.Date(string="Appointment Date") 12 | 13 | def print_report(self): 14 | data = { 15 | 'model': 'create.appointment', 16 | 'form': self.read()[0] 17 | } 18 | # if data['form']['patient_id']: 19 | # selected_patient = data['form']['patient_id'][0] 20 | # appointments = self.env['hospital.appointment'].search([('patient_id', '=', selected_patient)]) 21 | # else: 22 | # appointments = self.env['hospital.appointment'].search([]) 23 | # appointment_list = [] 24 | # for app in appointments: 25 | # vals = { 26 | # 'name': app.name, 27 | # 'notes': app.notes, 28 | # 'appointment_date': app.appointment_date 29 | # } 30 | # appointment_list.append(vals) 31 | # # print("appointments", appointments) 32 | # data['appointments'] = appointment_list 33 | # # print("Data", data) 34 | return self.env.ref('om_hospital.report_appointment').with_context(landscape=True).report_action(self, data=data) 35 | 36 | def delete_patient(self): 37 | for rec in self: 38 | rec.patient_id.unlink() 39 | # print("Test". rec) 40 | 41 | # Create Record From Code 42 | # https://www.youtube.com/watch?v=Jssb15ADeyg&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=40 43 | def create_appointment(self): 44 | vals = { 45 | 'patient_id': self.patient_id.id, 46 | 'appointment_date': self.appointment_date, 47 | 'notes': 'Created From The Wizard/Code' 48 | } 49 | # adding a message to the chatter from code 50 | # https://www.youtube.com/watch?v=J3MvgwHnR0A&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=48 51 | self.patient_id.message_post(body="Test string ", subject="Appointment Creation") 52 | # creating appointments from the code 53 | new_appointment = self.env['hospital.appointment'].create(vals) 54 | context = dict(self.env.context) 55 | import logging 56 | _logger = logging.getLogger(__name__) 57 | _logger.info("account.py cornerstone_account calling") 58 | context['form_view_initial_mode'] = 'edit' 59 | return {'type': 'ir.actions.act_window', 60 | 'view_type': 'form', 61 | 'view_mode': 'form', 62 | 'res_model': 'hospital.appointment', 63 | 'res_id': new_appointment.id, 64 | 'context': context 65 | } 66 | 67 | # Fetching/ Taking Data From Database Tables 68 | # https://www.youtube.com/watch?v=hUPSvL8GTQE&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=49 69 | def get_data(self): 70 | appointments = self.env['hospital.appointment'].search([]) 71 | for rec in appointments: 72 | print("Appointment Name", rec.name) 73 | # How to Prevent Wizard Getting Closed After Button Click 74 | # https://www.youtube.com/watch?v=n5La3aTue7o&list=PLqRRLx0cl0hoJhjFWkFYowveq2Zn55dhM&index=68 75 | return{ 76 | "type": "ir.actions.do_nothing" 77 | } 78 | -------------------------------------------------------------------------------- /om_hospital/wizards/create_appointment.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | create.appointment.wizard 10 | create.appointment 11 | 12 |
13 | 14 | 15 | 16 | 17 |
18 |
24 |
25 |
26 |
27 | 28 | 29 | Create Appointment 30 | ir.actions.act_window 31 | create.appointment 32 | form 33 | 34 | new 35 | 36 | 37 |
38 | --------------------------------------------------------------------------------