168 lines
5.6 KiB
Python
168 lines
5.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Copyright 2024-2026 Nexa Systems Inc.
|
|
# License OPL-1 (Odoo Proprietary License v1.0)
|
|
|
|
from datetime import timedelta
|
|
|
|
from odoo import models, fields, api, _
|
|
|
|
|
|
class FusionLTCCleanup(models.Model):
|
|
_name = 'fusion.ltc.cleanup'
|
|
_description = 'LTC Cleanup Schedule'
|
|
_inherit = ['mail.thread', 'mail.activity.mixin']
|
|
_order = 'scheduled_date desc, id desc'
|
|
|
|
name = fields.Char(
|
|
string='Reference',
|
|
required=True,
|
|
copy=False,
|
|
readonly=True,
|
|
default=lambda self: _('New'),
|
|
)
|
|
facility_id = fields.Many2one(
|
|
'fusion.ltc.facility',
|
|
string='LTC Facility',
|
|
required=True,
|
|
tracking=True,
|
|
index=True,
|
|
)
|
|
scheduled_date = fields.Date(
|
|
string='Scheduled Date',
|
|
required=True,
|
|
tracking=True,
|
|
)
|
|
completed_date = fields.Date(
|
|
string='Completed Date',
|
|
tracking=True,
|
|
)
|
|
state = fields.Selection([
|
|
('scheduled', 'Scheduled'),
|
|
('in_progress', 'In Progress'),
|
|
('completed', 'Completed'),
|
|
('cancelled', 'Cancelled'),
|
|
('rescheduled', 'Rescheduled'),
|
|
], string='Status', default='scheduled', required=True, tracking=True)
|
|
|
|
technician_id = fields.Many2one(
|
|
'res.users',
|
|
string='Technician',
|
|
tracking=True,
|
|
)
|
|
task_id = fields.Many2one(
|
|
'fusion.technician.task',
|
|
string='Field Service Task',
|
|
)
|
|
notes = fields.Text(string='Notes')
|
|
items_cleaned = fields.Integer(string='Items Cleaned')
|
|
photo_ids = fields.Many2many(
|
|
'ir.attachment',
|
|
'ltc_cleanup_photo_rel',
|
|
'cleanup_id',
|
|
'attachment_id',
|
|
string='Photos',
|
|
)
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals_list):
|
|
for vals in vals_list:
|
|
if vals.get('name', _('New')) == _('New'):
|
|
vals['name'] = self.env['ir.sequence'].next_by_code('fusion.ltc.cleanup') or _('New')
|
|
return super().create(vals_list)
|
|
|
|
def action_start(self):
|
|
self.write({'state': 'in_progress'})
|
|
|
|
def action_complete(self):
|
|
self.write({
|
|
'state': 'completed',
|
|
'completed_date': fields.Date.context_today(self),
|
|
})
|
|
for record in self:
|
|
record._schedule_next_cleanup()
|
|
record.message_post(
|
|
body=_("Cleanup completed. Items cleaned: %s", record.items_cleaned or 0),
|
|
message_type='comment',
|
|
)
|
|
|
|
def action_cancel(self):
|
|
self.write({'state': 'cancelled'})
|
|
|
|
def action_reschedule(self):
|
|
self.write({'state': 'rescheduled'})
|
|
|
|
def action_reset(self):
|
|
self.write({'state': 'scheduled'})
|
|
|
|
def _schedule_next_cleanup(self):
|
|
facility = self.facility_id
|
|
interval = facility._get_cleanup_interval_days()
|
|
next_date = (self.completed_date or fields.Date.context_today(self)) + timedelta(days=interval)
|
|
facility.next_cleanup_date = next_date
|
|
|
|
next_cleanup = self.env['fusion.ltc.cleanup'].create({
|
|
'facility_id': facility.id,
|
|
'scheduled_date': next_date,
|
|
'technician_id': self.technician_id.id if self.technician_id else False,
|
|
})
|
|
|
|
self.activity_schedule(
|
|
'mail.mail_activity_data_todo',
|
|
date_deadline=next_date - timedelta(days=7),
|
|
summary=_('Upcoming cleanup at %s', facility.name),
|
|
note=_('Next cleanup is scheduled for %s at %s.', next_date, facility.name),
|
|
)
|
|
return next_cleanup
|
|
|
|
def action_create_task(self):
|
|
self.ensure_one()
|
|
if self.task_id:
|
|
return {
|
|
'type': 'ir.actions.act_window',
|
|
'res_model': 'fusion.technician.task',
|
|
'view_mode': 'form',
|
|
'res_id': self.task_id.id,
|
|
}
|
|
task = self.env['fusion.technician.task'].create({
|
|
'task_type': 'ltc_visit',
|
|
'facility_id': self.facility_id.id,
|
|
'scheduled_date': self.scheduled_date,
|
|
'technician_id': self.technician_id.id if self.technician_id else False,
|
|
'description': _('Cleanup visit at %s', self.facility_id.name),
|
|
})
|
|
self.task_id = task.id
|
|
return {
|
|
'type': 'ir.actions.act_window',
|
|
'res_model': 'fusion.technician.task',
|
|
'view_mode': 'form',
|
|
'res_id': task.id,
|
|
}
|
|
|
|
@api.model
|
|
def _cron_schedule_cleanups(self):
|
|
today = fields.Date.context_today(self)
|
|
week_ahead = today + timedelta(days=7)
|
|
facilities = self.env['fusion.ltc.facility'].search([
|
|
('active', '=', True),
|
|
('cleanup_frequency', '!=', False),
|
|
('next_cleanup_date', '<=', week_ahead),
|
|
('next_cleanup_date', '>=', today),
|
|
])
|
|
for facility in facilities:
|
|
existing = self.search([
|
|
('facility_id', '=', facility.id),
|
|
('scheduled_date', '=', facility.next_cleanup_date),
|
|
('state', 'not in', ['cancelled', 'rescheduled']),
|
|
], limit=1)
|
|
if not existing:
|
|
cleanup = self.create({
|
|
'facility_id': facility.id,
|
|
'scheduled_date': facility.next_cleanup_date,
|
|
})
|
|
cleanup.activity_schedule(
|
|
'mail.mail_activity_data_todo',
|
|
date_deadline=facility.next_cleanup_date - timedelta(days=3),
|
|
summary=_('Cleanup scheduled at %s', facility.name),
|
|
note=_('Cleanup is scheduled for %s.', facility.next_cleanup_date),
|
|
)
|