102 lines
3.5 KiB
Python
102 lines
3.5 KiB
Python
# pyrefly: ignore [missing-import]
|
|
from odoo import api, fields, models
|
|
# pyrefly: ignore [missing-import]
|
|
from odoo.exceptions import ValidationError
|
|
|
|
|
|
class EducationHostelVisitor(models.Model):
|
|
_name = 'education.hostel.visitor'
|
|
_description = 'Hostel Visitor Log'
|
|
_inherit = ['mail.thread', 'mail.activity.mixin']
|
|
_order = 'visit_date desc, id desc'
|
|
|
|
name = fields.Char(
|
|
string='Reference',
|
|
required=True,
|
|
copy=False,
|
|
readonly=True,
|
|
default=lambda self: self.env['ir.sequence'].next_by_code('education.hostel.visitor'),
|
|
index=True,
|
|
)
|
|
student_id = fields.Many2one(
|
|
'education.student',
|
|
string='Student (Host)',
|
|
required=True,
|
|
ondelete='restrict',
|
|
index=True,
|
|
tracking=True,
|
|
)
|
|
hostel_id = fields.Many2one(
|
|
'education.hostel',
|
|
string='Hostel',
|
|
required=True,
|
|
ondelete='restrict',
|
|
index=True,
|
|
)
|
|
visitor_name = fields.Char(string='Visitor Name', required=True)
|
|
relationship = fields.Char(string='Relationship')
|
|
phone = fields.Char(string='Visitor Phone')
|
|
purpose = fields.Text(string='Purpose of Visit')
|
|
visit_date = fields.Date(string='Visit Date', required=True, default=fields.Date.context_today)
|
|
check_in = fields.Datetime(string='Check In', tracking=True)
|
|
check_out = fields.Datetime(string='Check Out', tracking=True)
|
|
approved_by = fields.Many2one(
|
|
'res.users',
|
|
string='Approved By',
|
|
tracking=True,
|
|
domain=[('share', '=', False)],
|
|
)
|
|
state = fields.Selection([
|
|
('pending', 'Pending'),
|
|
('approved', 'Approved'),
|
|
('checked_in', 'Checked In'),
|
|
('checked_out', 'Checked Out'),
|
|
('rejected', 'Rejected'),
|
|
], string='Status', default='pending', required=True, tracking=True, index=True)
|
|
company_id = fields.Many2one(
|
|
'res.company',
|
|
string='Company',
|
|
required=True,
|
|
default=lambda self: self.env.company,
|
|
index=True,
|
|
)
|
|
|
|
# ── Workflow ──────────────────────────────────────────────────────────────
|
|
|
|
def action_approve(self):
|
|
for rec in self:
|
|
rec.state = 'approved'
|
|
rec.approved_by = self.env.user
|
|
|
|
def action_reject(self):
|
|
self.write({'state': 'rejected'})
|
|
|
|
def action_check_in(self):
|
|
for rec in self:
|
|
if rec.state != 'approved':
|
|
raise ValidationError("Visitor must be approved before check-in.")
|
|
rec.check_in = fields.Datetime.now()
|
|
rec.state = 'checked_in'
|
|
|
|
def action_check_out(self):
|
|
for rec in self:
|
|
if rec.state != 'checked_in':
|
|
raise ValidationError("Visitor must be checked in before check-out.")
|
|
rec.check_out = fields.Datetime.now()
|
|
rec.state = 'checked_out'
|
|
|
|
@api.constrains('check_in', 'check_out')
|
|
def _check_times(self):
|
|
for rec in self:
|
|
if rec.check_in and rec.check_out and rec.check_out < rec.check_in:
|
|
raise ValidationError('Check-out time cannot be before check-in time.')
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals_list):
|
|
for vals in vals_list:
|
|
if not vals.get('name') or vals.get('name') == '/':
|
|
vals['name'] = (
|
|
self.env['ir.sequence'].next_by_code('education.hostel.visitor') or '/'
|
|
)
|
|
return super().create(vals_list)
|