import ast import datetime import json import re import uuid import logging import base64 import subprocess import tempfile import easywebdav import os import os.path from odoo import api, fields, models, _ from odoo import tools from odoo.exceptions import ValidationError from datetime import date from datetime import datetime from dateutil.relativedelta import relativedelta from pyffmpeg import FFmpeg from tuya_iot import TuyaOpenAPI, TUYA_LOGGER from tuya_connector import TuyaOpenAPI, TUYA_LOGGER import sys TUYA_LOGGER.setLevel(logging.DEBUG) _logger = logging.getLogger(__name__) class dssmaintaintasks(models.Model): _name = "dss.maintaintask" _description = "DigitalSignage Wartungsarbeiten" _inherit = ['mail.thread','mail.activity.mixin'] _rec_name = "maintainname" maintainname = fields.Char('Einsatzbezeichnung', required=True) uuid = fields.Char(default=lambda self: self._default_uuid(), required=True, readonly=True, copy=False, string='UUID') date_create = fields.Date('Erstellungsdatum', default=lambda self: self._default_create_date()) date_lastedit = fields.Date('Änderungsdatum') user_create = fields.Char('Erstellungsuser', default=lambda self: self._default_create_user()) user_lastedit = fields.Char('Änderungsuser') maintaintyp = fields.Selection([('AUF','Aufbau/Installation'),('REP','Reparatur'), ('CLE','Reinigung'), ('INS','Inspektion'), ('ABB','Demontage'), ('REN','Erneuerung'),('SON','Sonstiges')],tracking=True) project = fields.Many2one('dss.projects', required=True, tracking=True) maintain_tag = fields.Date('Einsatztag', tracking=True) maintain_time_h = fields.Integer('Einsatzzeit Volle Stunden', tracking=True) maintain_time_m = fields.Integer('Einsatzzeit Rest Minuten', tracking=True) # maintain_people = fields.Many2many('res.partner','Einsatzbeteiligte', domain="['&',('dssinternpartner','=',True),('dssinternpartner_grafik','=',True)]", tracking=True,required=True) maintain_reason = fields.Char('Einsatzgrund', required=True) maintain_text = fields.Html('Einsatzablauf', required=True) maintain_travel_start = fields.Datetime('Anreisebeginn', tracking=True) maintain_travel_end = fields.Datetime('Ankunftszeit', tracking=True) maintain_travel_distance = fields.Float('Anreise Entfernung', tracking=True) maintain_travel_duration = fields.Float('Anreise Dauer', tracking=True, compute='_compute_travel_total_time', store=True) maintain_travel_duration_text = fields.Char('Anreise Dauer', tracking=True, compute='_compute_travel_total_time_text', store=True) maintain_work_start = fields.Datetime('Arbeitsbeginn', tracking=True) maintain_work_end = fields.Datetime('Arbeitsende', tracking=True) maintain_work_duration = fields.Float('Arbeits Dauer', tracking=True,compute='_compute_work_total_time', store=True) maintain_work_duration_text = fields.Char('Arbeits Dauer', tracking=True, compute='_compute_work_total_time_text', store=True) maintain_return_start = fields.Datetime('Rückreisebeginn', tracking=True) maintain_return_end = fields.Datetime('Rückreiseende', tracking=True) maintain_return_duration = fields.Float('Rückreise Dauer', tracking=True,compute='_compute_return_total_time', store=True) maintain_return_distance = fields.Float('Rückreise Entfernung', tracking=True) maintain_return_duration_text = fields.Char('Rückreise Dauer', tracking=True, compute='_compute_return_total_time_text', store=True) maintain_total_start = fields.Datetime('Einsatzbeginn', tracking=True,compute='_compute_maintain_total_start', store=True) maintain_total_end = fields.Datetime('Einsatzende', tracking=True, compute='_compute_maintain_total_end', store=True) maintain_total_duration = fields.Float('Einsatz Dauer', tracking=True,compute='_compute_maintain_total_time', store=True) maintain_total_duration_text = fields.Char('Einsatz Dauer', tracking=True, compute='_compute_maintain_total_time_text', store=True) maintain_total_duration_money = fields.Float('Einsatz Kosten', tracking=True, compute='_compute_maintain_total_cost', store=True) maintain_is_calculate = fields.Boolean('Einsatz ist Abrechenbar', default=False, tracking=True) maintain_employee =fields.Many2many('hr.employee', string='Einsatzmitarbeiter', tracking=True, required=True) @api.depends('maintain_employee') @api.onchange('maintain_employee') def _compute_maintain_total_cost(self): for record in self: total_cost = 0.0 if record.maintain_employee: for employee in record.maintain_employee: if employee.hourly_cost: # Calculate the total cost for each employee based on their hourly cost and the total duration of the maintenance task total_cost += employee.hourly_cost * record.maintain_total_duration record.maintain_total_duration_money = total_cost @api.depends('maintain_travel_duration') @api.onchange('maintain_travel_duration') def _compute_travel_total_time_text(self): for record in self: if record.maintain_travel_duration: hours = int(record.maintain_travel_duration) minutes = int((record.maintain_travel_duration - hours) * 60) record.maintain_travel_duration_text = f"{hours} Stunden {minutes} Minuten" else: record.maintain_travel_duration_text = "0 Stunden 0 Minuten" @api.depends('maintain_work_duration') @api.onchange('maintain_work_duration') def _compute_work_total_time_text(self): for record in self: if record.maintain_work_duration: hours = int(record.maintain_work_duration) minutes = int((record.maintain_work_duration - hours) * 60) record.maintain_work_duration_text = f"{hours} Stunden {minutes} Minuten" else: record.maintain_work_duration_text = "0 Stunden 0 Minuten" @api.depends('maintain_return_duration') @api.onchange('maintain_return_duration') def _compute_return_total_time_text(self): for record in self: if record.maintain_return_duration: hours = int(record.maintain_return_duration) minutes = int((record.maintain_return_duration - hours) * 60) record.maintain_return_duration_text = f"{hours} Stunden {minutes} Minuten" else: record.maintain_return_duration_text = "0 Stunden 0 Minuten" @api.depends('maintain_total_duration') @api.onchange('maintain_total_duration') def _compute_maintain_total_time_text(self): for record in self: if record.maintain_total_duration: hours = int(record.maintain_total_duration) minutes = int((record.maintain_total_duration - hours) * 60) record.maintain_total_duration_text = f"{hours} Stunden {minutes} Minuten" else: record.maintain_total_duration_text = "0 Stunden 0 Minuten" @api.constrains('maintain_travel_start', 'maintain_travel_end') @api.onchange('maintain_travel_start', 'maintain_travel_end') def _compute_travel_total_time(self): for record in self: if record.maintain_travel_start and record.maintain_travel_end: if record.maintain_travel_start >= record.maintain_travel_end: raise ValidationError(_("Anreisebeginn muss vor Ankunftszeit liegen.")) record.maintain_travel_duration = (record.maintain_travel_end - record.maintain_travel_start).total_seconds() / 3600.0 @api.constrains('maintain_work_start', 'maintain_work_end') @api.onchange('maintain_work_start', 'maintain_work_end') def _compute_work_total_time(self): for record in self: if record.maintain_work_start and record.maintain_work_end: if record.maintain_work_start >= record.maintain_work_end: raise ValidationError(_("Arbeitsbeginn muss vor Arbeitsende liegen.")) record.maintain_work_duration = (record.maintain_work_end - record.maintain_work_start).total_seconds() / 3600.0 @api.constrains('maintain_return_start', 'maintain_return_end') @api.onchange('maintain_return_start', 'maintain_return_end') def _compute_return_total_time(self): for record in self: if record.maintain_return_start and record.maintain_return_end: if record.maintain_return_start >= record.maintain_return_end: raise ValidationError(_("Rückreisebeginn muss vor Rückreiseende liegen.")) record.maintain_return_duration = (record.maintain_return_end - record.maintain_return_start).total_seconds() / 3600.0 @api.depends('maintain_travel_start', 'maintain_work_start', 'maintain_return_start') def _compute_maintain_total_start(self): for record in self: if record.maintain_travel_start and record.maintain_work_start and record.maintain_return_start: # Find the earliest start time among travel, work, and return earliest_start = min(record.maintain_travel_start, record.maintain_work_start, record.maintain_return_start) record.maintain_total_start = earliest_start else: record.maintain_total_start = False @api.depends('maintain_travel_end', 'maintain_work_end', 'maintain_return_end') def _compute_maintain_total_end(self): for record in self: if record.maintain_travel_end and record.maintain_work_end and record.maintain_return_end: # Find the latest end time among travel, work, and return latest_end = max(record.maintain_travel_end, record.maintain_work_end, record.maintain_return_end) record.maintain_total_end = latest_end else: record.maintain_total_end = False @api.depends('maintain_travel_duration', 'maintain_work_duration', 'maintain_return_duration') @api.onchange('maintain_travel_duration', 'maintain_work_duration', 'maintain_return_duration') def _compute_maintain_total_time(self): for record in self: total_duration = 0.0 if record.maintain_travel_duration: total_duration += record.maintain_travel_duration if record.maintain_work_duration: total_duration += record.maintain_work_duration if record.maintain_return_duration: total_duration += record.maintain_return_duration record.maintain_total_duration = total_duration @api.model def _default_uuid(self): return str(uuid.uuid4()) def _default_create_date(self): return str(date.today()) def _default_create_user(self): return str(self.env.user.name)