trytondo-optical_equipment/maintenance.py
2024-04-20 17:35:18 +00:00

1109 lines
37 KiB
Python

# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.model import (
Workflow,
ModelSQL,
ModelView,
fields,
)
from trytond.wizard import Button, StateAction, StateView, Wizard
from trytond.modules.company import CompanyReport
from trytond.transaction import Transaction
from trytond.pyson import Bool, Eval, If, Id
from trytond.pool import Pool
from datetime import timedelta
from scipy.stats import t
import matplotlib.pyplot as plt
import math as mt
from io import BytesIO
from trytond.exceptions import UserError
from trytond.i18n import gettext
_digits = (16, 2)
class MaintenanceService(Workflow, ModelSQL, ModelView):
'Equipment Maintenance Service'
__name__ = 'optical_equipment_maintenance.service'
_rec_name = 'rec_name'
_order_name = 'code'
_states = {'readonly': (Eval('state') != 'draft')}
code = fields.Char(
'Code',
readonly=True,
)
reference = fields.Char(
'Reference', help='The identification of an external origin.'
)
description = fields.Char('Description', states=_states)
sale_date = fields.Char('Sale Date')
contract_origin = fields.Reference(
'Contract Base',
selection='get_origin_contract',
)
sale_origin = fields.Reference(
'Sale Origin', selection='get_origin', states={'readonly': True}
)
company = fields.Many2One('company.company', 'Company', readonly=True)
maintenance_type = fields.Selection(
[
('initial', 'Initial'),
('preventive', 'Preventive'),
('corrective', 'Corrective'),
],
'Maintenance Type',
states=_states,
)
propietary = fields.Many2One(
'party.party', 'Propietary', required=True, states=_states
)
propietary_address = fields.Many2One(
'party.address',
'Propietary Address',
required=True,
domain=[('party', '=', Eval('propietary'))],
states=_states,
)
lines = fields.One2Many(
'optical_equipment.maintenance', 'service_maintenance', 'Lines'
)
estimated_agended = fields.DateTime('Date Maintenance', readonly=True)
current_agended = fields.Many2One(
'optical_equipment_maintenance.diary', 'Current Agended',
states=_states
)
history_agended = fields.Many2Many(
'optical_equipment_maintenance.service-maintenance.diary',
'maintenance_service',
'agended',
'History Agended',
readonly=True,
)
state_agended = fields.Selection(
[
('no_agenda', 'No agenda'),
('agended', 'Agended'),
('in_progress', 'In progress'),
('finish', 'Finish'),
('failed', 'Failed'),
],
'State Agenda',
readonly=True,
)
technical = fields.Many2One('company.employee', 'Technical', readonly=True)
state = fields.Selection(
[
('draft', 'Draft'),
('agended', 'Agended'),
('in_progress', 'In Progress'),
('failed', 'Failed'),
('finished', 'Finished'),
],
'State',
required=True,
readonly=True,
sort=True,
)
rec_name = fields.Function(fields.Char('rec_name'), 'get_rec_name')
temperature_min = fields.Float(
'Temp Min'
)
temperature_max = fields.Float(
'Temp Max'
)
temperature_uom = fields.Many2One(
'product.uom',
'Temperature UOM',
domain=[
('category', '=', Id('optical_equipment', 'uom_cat_temperature'))
],
)
moisture_min = fields.Float('Moisture Min')
moisture_max = fields.Float('Moisture Max')
moisture_uom = fields.Many2One(
'product.uom',
'Moisture UOM',
domain=[
('category', '=',
Id('optical_equipment', 'uom_cat_relative_humedity'))
],
)
technician_responsible = fields.Char('Technician Responsible')
invima = fields.Char('Invima')
technician_signature = fields.Binary('Technician Signature')
@fields.depends('maintenance_type', 'code')
def get_rec_name(self, name):
if self.maintenance_type and self.code:
name = str(self.maintenance_type) + '@' + str(self.code)
else:
name = str(self.maintenance_type) + '@' + 'Borrador'
return name
@classmethod
def __setup__(cls):
super(MaintenanceService, cls).__setup__()
cls._order = [('code', 'DESC'), ('id', 'DESC')]
cls._transitions = {
('draft', 'agended'),
('agended', 'in_progress'),
('in_progress', 'finished'),
}
cls._buttons.update(
{
'reassing_agended': {
'invisible':
Eval('state') != 'failed'
},
'assing_agended': {
'invisible':
Eval('state') != 'draft'
},
'in_progress': {
'invisible':
Eval('state').in_(['draft', 'in_progress', 'finished'])
},
'finished': {
'invisible':
Eval('state').in_(['draft', 'agended', 'finished'])
},
}
)
@staticmethod
def default_company():
return Transaction().context.get('company')
@staticmethod
def default_temperature_min():
pool = Pool()
Config = pool.get('optical_equipment.configuration')
config = Config(1)
temperature_min = config.temperature_min
return temperature_min
@staticmethod
def default_temperature_max():
pool = Pool()
Config = pool.get('optical_equipment.configuration')
config = Config(1)
temperature_max = config.temperature_max
return temperature_max
@staticmethod
def default_moisture_min():
pool = Pool()
Config = pool.get('optical_equipment.configuration')
config = Config(1)
moisture_min = config.moisture_min
return moisture_min
@staticmethod
def default_temperature_uom():
pool = Pool()
Config = pool.get('optical_equipment.configuration')
config = Config(1)
if config.temperature_uom:
temperature_uom = config.temperature_uom.id
return temperature_uom
@staticmethod
def default_moisture_uom():
pool = Pool()
Config = pool.get('optical_equipment.configuration')
config = Config(1)
if config.moisture_uom:
moisture_uom = config.moisture_uom.id
return moisture_uom
@staticmethod
def default_moisture_max():
pool = Pool()
Config = pool.get('optical_equipment.configuration')
config = Config(1)
moisture_max = config.moisture_max
return moisture_max
@classmethod
def default_maintenance_type(self):
return 'preventive'
@classmethod
def default_state_agended(self):
return 'no_agenda'
@classmethod
def default_state(self):
return 'draft'
@classmethod
def default_technician_responsible(cls):
pool = Pool()
ConfigurationEquipment = pool.get('optical_equipment.configuration')
config = ConfigurationEquipment(1)
if config.technician_responsible:
technician_responsible = config.technician_responsible
return technician_responsible.party.name
@classmethod
def default_invima(cls):
pool = Pool()
ConfigurationEquipment = pool.get('optical_equipment.configuration')
config = ConfigurationEquipment(1)
if config.technician_responsible:
return config.technician_responsible.invima
@classmethod
def default_technician_signature(cls):
pool = Pool()
ConfigurationEquipment = pool.get('optical_equipment.configuration')
config = ConfigurationEquipment(1)
if config.technician_signature:
return config.technician_signature
@classmethod
def _get_origin(cls):
'Return list of Model names for origin Reference'
pool = Pool()
Sale = pool.get('sale.sale')
SaleLine = pool.get('sale.line')
return [Sale.__name__, SaleLine.__name__]
@classmethod
def get_origin(cls):
Model = Pool().get('ir.model')
get_name = Model.get_name
models = cls._get_origin()
return [(None, '')] + [(m, get_name(m)) for m in models]
@classmethod
def _get_origin_contract(cls):
'Return list of Model names for origin Reference'
pool = Pool()
Contract = pool.get('optical_equipment.contract')
return [Contract.__name__]
@classmethod
def get_origin_contract(cls):
Model = Pool().get('ir.model')
get_name = Model.get_name
models = cls._get_origin_contract()
return [(None, '')] + [(m, get_name(m)) for m in models]
@classmethod
def set_code(cls, maintenance):
pool = Pool()
Config = pool.get('optical_equipment.configuration')
config = Config(2)
if config.maintenance_sequence is not None:
if not maintenance.code:
try:
maintenance.code = config.maintenance_sequence.get()
maintenance.save()
except UserError:
raise UserError(str('Validation Error'))
else:
raise UserError(
gettext('optical_equipment.msg_not_sequence_equipment'))
@classmethod
@ModelView.button_action('optical_equipment.act_assing_agended')
def assing_agended(cls, maintenances):
pass
@classmethod
@ModelView.button_action('optical_equipment.act_reassing_agended')
def reassing_agended(cls, maintenances):
pass
@classmethod
@ModelView.button
@Workflow.transition('in_progress')
def in_progress(cls, maintenances):
pass
@classmethod
@ModelView.button
@Workflow.transition('finished')
def finished(cls, maintenances):
for maintenance in maintenances:
for line in maintenance.lines:
if line.state != 'finished':
raise Exception(
"Debe Finalizar Todas las lineas de mantenimiento")
class MaintenanceServiceLine(Workflow, ModelSQL, ModelView):
'Equipment Maintenance Line'
__name__ = 'optical_equipment.maintenance'
# _rec_name = 'rec_name'
_states = {'required': True, 'readonly': Eval('state').in_(['finished'])}
service_maintenance = fields.Many2One(
'optical_equipment_maintenance.service',
'Maintenance Service',
ondelete='CASCADE',
domain=[
('state', 'in', ['draft', 'in_progress', 'finished']),
('propietary', '=', Eval('propietary')),
],
states=_states,
)
code = fields.Char('Code', states={'readonly': True})
maintenance_type = fields.Selection(
[
('initial', 'Initial'),
('preventive', 'Preventive'),
('corrective', 'Corrective'),
],
'Maintenance Type',
states=_states,
)
state = fields.Selection(
[('draft', 'Draft'), ('finished', 'Finished')],
'State',
readonly=True,
sort=False,
states=_states,
)
company = fields.Many2One(
'company.company', 'Company', readonly=True)
propietary = fields.Many2One(
'party.party',
'Propietary',
states=_states,
)
propietary_address = fields.Many2One(
'party.address',
'Propietary Address',
states=_states,
domain=[('party', '=', Eval('propietary'))],
)
equipment = fields.Many2One(
'optical_equipment.equipment',
'Equipment',
domain=[
('state', 'in', ['registred', 'uncontrated', 'contrated']),
('propietary', '=', Eval('propietary')),
('propietary_address', '=', Eval('propietary_address')),
],
states=_states,
)
equipment_calibrate = fields.Boolean(
'Calibrate Equipment', states={'readonly': True}
)
# Preventive maintenance
initial_operation = fields.Boolean(
'Verificación inicial de funcionamiento')
check_equipment = fields.Boolean('Revisión del Equipo')
check_electric_system = fields.Boolean('Revisión del sistema electríco')
clean_int_ext = fields.Boolean('Limpieza interior y exterior')
clean_eyes = fields.Boolean('Limpieza de lentes y espejos')
check_calibration = fields.Boolean('Verificar Calibración')
maintenance_activity = fields.One2Many(
'optical_equipment_maintenance.activity',
'maintenance', 'Maintenance Activitys'
)
# Calibration
patterns_equipments = fields.Char(
'K Pattern',
states={'readonly': True},
)
lines_calibration = fields.One2Many(
'optical_equipment.maintenance.calibration_sample',
'maintenance',
'Lines of Calibration',
states={'readonly': Eval('state') == 'finished'},
)
calibration_total = fields.One2Many(
'optical_equipment.maintenance.calibration',
'maintenance',
'Calibration Total',
states={'readonly': Eval('state') == 'finished'},
)
maintenance_lines = fields.One2Many(
'optical_equipment.maintenance.line', 'maintenance', 'Lines'
)
description_activity = fields.Char('Activity')
next_maintenance = fields.Function(
fields.Date('Next Maintenance'), 'get_next_maintenance'
)
temperature_min = fields.Float('Temp Min')
temperature_max = fields.Float('Temp Max')
temperature_uom = fields.Many2One(
'product.uom',
'Temperature UOM',
domain=[
('category', '=', Id('optical_equipment', 'uom_cat_temperature'))
],
)
moisture_min = fields.Float('Moisture Min')
moisture_max = fields.Float('Moisture Max')
moisture_uom = fields.Many2One(
'product.uom',
'Moisture UOM',
domain=[
('category', '=',
Id('optical_equipment', 'uom_cat_relative_humedity'))
],
)
graph_calibration = fields.Binary('Graphs')
rec_name = fields.Function(fields.Char('rec_name'), 'get_rec_name')
technician_responsible = fields.Char('Technician Responsible')
invima = fields.Char('Invima')
technician_signature = fields.Binary('Technician Signature')
@classmethod
def __setup__(cls):
super(MaintenanceServiceLine, cls).__setup__()
cls._transitions.update({('draft', 'finished')})
cls._buttons.update({
'in_progress': {
'invisible':
Eval('state').in_(['draft', 'in_progress', 'finished'])
},
'samples': {
'invisible': (
(Eval('state').in_(['finished'])) | (
Eval('lines_calibration', [0])) | (
~Eval('equipment_calibrate')))
},
'calibrate': {
'invisible': (Eval('lines_calibration', [0])) | (
Eval('state').in_(['finished'])),
'depends': ['state'], },
'finished': {'invisible': (Eval('state').in_(['finished'])) |
((Eval('maintenance_type') == 'corrective') & (Eval('maintenance_lines') == ()))},
})
@classmethod
def default_technician_responsible(cls):
pool = Pool()
ConfigurationEquipment = pool.get('optical_equipment.configuration')
config = ConfigurationEquipment(1)
if config.technician_responsible:
technician_responsible = config.technician_responsible
return technician_responsible.party.name
@classmethod
def default_invima(cls):
pool = Pool()
ConfigurationEquipment = pool.get('optical_equipment.configuration')
config = ConfigurationEquipment(1)
if config.technician_responsible:
return config.technician_responsible.invima
@classmethod
def default_technician_signature(cls):
pool = Pool()
ConfigurationEquipment = pool.get('optical_equipment.configuration')
config = ConfigurationEquipment(1)
if config.technician_signature:
return config.technician_signature
@staticmethod
def default_company():
return Transaction().context.get('company')
@classmethod
def default_state(cls):
return 'draft'
@classmethod
def default_maintenance_type(cls):
return 'preventive'
@classmethod
def view_attributes(cls):
return super(MaintenanceServiceLine, cls).view_attributes() + [
(
"//page[@id='preventive']",
'states',
{
'invisible':
If(Eval('maintenance_type') == 'corrective', True),
},
),
(
"//page[@id='corrective']",
'states',
{
'invisible':
If(Eval('maintenance_type') != 'corrective', True),
},
),
(
"//page[@id='calibration']",
'states',
{
'invisible': ~Eval('equipment_calibrate'),
},
),
(
"//page[@id='graph']",
'states',
{
'invisible': ~Eval('equipment_calibrate'),
},
),
]
@fields.depends('temperature_min', 'temperature_uom')
def on_change_temperature_min(self):
if self.temperature_min:
pool = Pool()
Measurements = pool.get('product.uom')
self.temperature_uom = Measurements.search(
['name', '=', 'Celsius'])[0].id
@fields.depends('moisture_min', 'moisture_uom')
def on_change_moisture_min(self):
pool = Pool()
Measurements = pool.get('product.uom')
self.moisture_uom = Measurements.search(
['name', '=', 'Relative Humedity']
)[0].id
@fields.depends('_parent_service_maintenance.propietary',
'_parent_service_maintenance.propietary_address',
'service_maintenance')
def on_change_service_maintenance(self):
if self.service_maintenance:
self.propietary = self.service_maintenance.propietary
self.propietary_address =\
self.service_maintenance.propietary_address
service = self.service_maintenance
self.temperature_min = service.temperature_min
self.temperature_max = service.temperature_max
self.temperature_uom = service.temperature_uom
self.moisture_min = service.moisture_min
self.moisture_max = service.moisture_max
self.moisture_uom = service.moisture_uom
else:
self.propietary = None
self.propietary_address = None
self.temperature_min = None
self.temperature_max = None
self.temperature_uom = None
self.moisture_min = None
self.moisture_max = None
self.moisture_uom = None
@fields.depends('equipment', 'patterns_equipments')
def on_change_equipment(self):
if self.equipment:
product = self.equipment.product
self.patterns_equipments = product.k_pattern
self.equipment_calibrate = product.calibration
self.initial_operation = product.initial_operation
self.check_equipment = product.check_equipment
self.check_electric_system = product.check_electric_system
self.clean_int_ext = product.clean_int_ext
self.clean_eyes = product.clean_eyes
self.check_calibration = product.check_calibration
else:
self.patterns_equipments = None
self.equipment_calibrate = False
self.initial_operation = False
self.check_equipment = False
self.check_electric_system = False
self.clean_int_ext = False
self.clean_eyes = False
self.check_calibration = False
def get_next_maintenance(self, action):
next_maintenance = None
if self.service_maintenance.estimated_agended:
if self.propietary.customer_type == 'ips':
next_maintenance = (
self.service_maintenance.estimated_agended
+ timedelta(days=182)
)
else:
next_maintenance = (
self.service_maintenance.estimated_agended
+ timedelta(days=365)
)
return next_maintenance
def get_standard_deviation(samples):
'''
This function calculated the
standartd deviation
'''
sum_samples = sum(samples)
n_samples = len(samples)
mean = sum_samples / n_samples
dev_std_square = sum(
(l - mean) ** 2 for l in samples) / (n_samples - 1)
dev_std = mt.sqrt(dev_std_square)
return dev_std
def get_uncertain_type_A(samples, dev_std):
'''
This function calculated the
uncertain type A
'''
n_samples = len(samples)
uncertain_type_A = dev_std / mt.sqrt(n_samples)
return uncertain_type_A
def get_create_graph(matrix, patterns, resolution, equipment_risk):
image = BytesIO()
errors = []
yerr = []
upresolution = resolution if resolution >= 0 else (resolution * -1)
lowresolution = resolution if resolution < 0 else (resolution * -1)
count = 0
for pattern in patterns:
error = pattern - matrix[count][0]
yerr.append(matrix[count][1])
errors.append(error)
count += 1
labels = list(patterns)
x = labels
y = errors
if equipment_risk == 'IIB':
if sum(errors) == 0:
top = 1.5
bottom = -1.5
else:
top = 2
bottom = -2
else:
top = 0.60
bottom = -0.60
ls = 'dotted'
fig, ax1 = plt.subplots(nrows=1, ncols=1)
# Límites del Eje Y
ax1.set_ylim(bottom, top)
# Límites del Eje X
ax1.set_xlim((min(labels) - 1, max(labels) + 1))
ax1.yaxis.grid(True)
ax1.xaxis.grid(True)
ax1.set_title('Error[D]')
ax1.set_xlabel('Patrones')
ax1.set_ylabel('Valores Observados')
ax1.set_yticks([lowresolution, 0.0, upresolution])
# ax1.set_xticks([-10.0,-5.0,0.0,5.0,10.0])
ax1.errorbar(x, y, yerr=yerr, marker='D', markersize=10, linestyle=ls)
plt.savefig(image, format='png')
plt.close()
return image.getvalue()
@classmethod
@ModelView.button
@Workflow.transition('in_progress')
def in_progress(cls, maintenances):
pass
@classmethod
@ModelView.button
@Workflow.transition('finished')
def finished(cls, maintenances):
for maintenance in maintenances:
if (
maintenance.equipment.product.calibration
and maintenance.calibration_total == ()
):
raise UserError(
'No puede finalizar este mantenimiento sin una calibración'
)
else:
maintenance.state = 'finished'
maintenance.code = maintenance.id
maintenance.save()
@classmethod
@ModelView.button
def samples(cls, maintenances):
pool = Pool()
CalibrationSample = pool.get(
'optical_equipment.maintenance.calibration_sample')
for maintenance in maintenances:
patterns = maintenance.equipment.product.k_pattern_list
for pattern in patterns:
samples = []
calibrationSample = CalibrationSample(
maintenance=maintenance.id,
product=maintenance.equipment.product.template.id,
value_patterns=pattern.id,
value_equipment=pattern.pattern,
mistake=0,
mistake_rate=0,
)
samples = [calibrationSample] * 5
maintenance.lines_calibration += tuple(samples)
maintenance.save()
@classmethod
@ModelView.button
def calibrate(cls, maintenances):
pool = Pool()
CalibrationLineTotal = pool.get(
'optical_equipment.maintenance.calibration')
dates = {}
dates_mistake_pattern = []
patterns = set()
for maintenance in maintenances:
maintenance.calibration_total = ()
if len(maintenance.lines_calibration) < 5:
raise UserError(
'Por favor Ingrese mas de 5 Muestras por patrón (Dioptría)'
)
for line in maintenance.lines_calibration:
if line.value_patterns.pattern not in patterns:
patterns.add(line.value_patterns.pattern)
dates[line.value_patterns.pattern] = [
line.value_equipment]
else:
dates[line.value_patterns.pattern].append(
line.value_equipment)
for pattern in patterns:
product = maintenance.equipment.product
samples = dates[pattern]
mean = sum(samples) / len(samples)
U_subi = product.Usubi
uncertain_pattern = product.uncertainy_pattern
MEP = product.MEP
dev_std = cls.get_standard_deviation(samples)
uncertain_type_A = cls.get_uncertain_type_A(samples, dev_std)
k_certificated_calibration = 2
uncertain_b1 = MEP / mt.sqrt(3) # Ub1_patron a 2 Decimales
if product.resolution_type == 'analoga':
a_resolution = product.analog_resolution
resolution = a_resolution
factor_a = product.a_factor_resolution
uncertain_b2_analog = (
a_resolution) / (factor_a * mt.sqrt(3))
sum_uncertain_c = (
(uncertain_type_A**2)
+ (uncertain_b1**2)
+ (uncertain_b2_analog**2)
)
uncertain_c = mt.sqrt(sum_uncertain_c)
uncertain_eff = uncertain_c**4 / (
(uncertain_type_A**4) / (len(samples) - 1)
+ (uncertain_b1**4 / U_subi)
+ (uncertain_b2_analog**4 / U_subi)
)
elif product.resolution_type == 'digital':
d_resolution = product.d_resolution
resolution = d_resolution
uncertain_b2_digital = (d_resolution) / (2 * mt.sqrt(3))
sum_uncertain_c = (
(uncertain_type_A**2)
+ (uncertain_b1**2)
+ (uncertain_b2_digital**2)
)
uncertain_c = mt.sqrt(sum_uncertain_c)
uncertain_eff = uncertain_c**4 / (
(uncertain_type_A**4) / (len(samples) - 1)
+ (uncertain_b1**4 / U_subi)
+ (uncertain_b2_digital**4 / U_subi)
)
t_student = t.ppf(1 - 0.025, uncertain_eff)
uncertain_expanded = round((t_student * uncertain_c), 2)
dates_mistake_pattern.append([mean, uncertain_expanded])
if product.resolution_type == 'analoga':
calibrationLineTotal = CalibrationLineTotal(
diopter=pattern,
mean=mean,
dev_std=dev_std,
uncertain_type_A=uncertain_type_A,
uncertain_pattern=uncertain_pattern,
k_c_calibration=k_certificated_calibration,
uncertain_U_b1=uncertain_b1,
d_resolution=a_resolution,
uncertain_U_b2_dig=0,
uncertain_U_b2_ana=uncertain_b2_analog,
uncertain_combinated=uncertain_c,
uncertain_eff=uncertain_eff,
t_student=t_student,
uncertain_expanded=uncertain_expanded,
state=(
'Aprobado'
if uncertain_expanded <= a_resolution
else 'Rechazado'
),
)
maintenance.calibration_total += (calibrationLineTotal,)
elif product.resolution_type == 'digital':
calibrationLineTotal = CalibrationLineTotal(
diopter=pattern,
mean=mean,
dev_std=dev_std,
uncertain_type_A=uncertain_type_A,
uncertain_pattern=uncertain_pattern,
k_c_calibration=k_certificated_calibration,
uncertain_U_b1=uncertain_b1,
d_resolution=d_resolution,
uncertain_U_b2_dig=uncertain_b2_digital,
uncertain_U_b2_ana=0,
uncertain_combinated=uncertain_c,
uncertain_eff=uncertain_eff,
t_student=t_student,
uncertain_expanded=uncertain_expanded,
state=(
'Aprobado'
if uncertain_expanded <= d_resolution
else 'Rechazado'
),
)
maintenance.calibration_total += (calibrationLineTotal,)
maintenance.save()
image = cls.get_create_graph(
dates_mistake_pattern, patterns, resolution, product.risk
)
maintenance.graph_calibration = image
maintenance.save()
class MaintenanceLine(ModelSQL, ModelView):
'Maintenance Line'
__name__ = 'optical_equipment.maintenance.line'
line_replace = fields.Boolean(
'Replace',
)
line_maintenance_activity = fields.Boolean(
'Maintenance Activity',
)
maintenance = fields.Many2One(
'optical_equipment.maintenance',
'Maintenance',
ondelete='CASCADE',
)
replacement = fields.Many2One(
'product.product',
'Replacement',
ondelete='RESTRICT',
domain=[('replacement', '=', True)],
depends={'line_replace'},
)
maintenance_activity = fields.Many2One(
'product.product',
'Maintenance activity',
domain=[('maintenance_activity', '=', True)],
depends={'line_maintenance_activity'},
)
quantity = fields.Float('Quantity', required=True, digits='unit')
# actual_quantity = fields.Float(
# 'Actual Quantity',
# digits='unit',
# readonly=True,
# states={
# 'invisible': Eval('type') != 'line',
# },
# )
unit = fields.Many2One(
'product.uom',
'Unit',
ondelete='RESTRICT',
states={
'readonly': Eval('_parent_maintenance.state') != 'draft',
},
domain=[
If(
Bool(Eval('product_uom_category')),
('category', '=', Eval('product_uom_category')),
('category', '!=', -1),
),
],
)
product_uom_category = fields.Function(
fields.Many2One('product.uom.category', 'Product Uom Category'),
'on_change_with_product_uom_category',
)
description = fields.Text(
'Description',
states={
'readonly': Eval('_parent_maintenance.state') != 'draft',
},
)
company = fields.Function(
fields.Many2One('company.company', 'Company'), 'on_change_with_company'
)
@fields.depends('replacement', 'maintenance_activity')
def on_change_with_product_uom_category(self, name=None):
if self.replacement:
return self.replacement.defaul_uom_category.id
if self.maintenance_activity:
return self.maintenance_activity.default_uom_category.id
@fields.depends('maintenance', '_parent_maintenance.company')
def on_change_with_company(self, name=None):
if self.maintenance and self.maintenance.company:
return self.maintenance.company.id
@fields.depends('line_replace', 'replacement')
def on_change_line_replace(self, name=None):
if not self.line_replace:
self.replacement = None
@fields.depends('line_maintenance_activity', 'maintenance_activity')
def on_change_line_maintenance_activity(self, name=None):
if not self.line_maintenance_activity:
self.maintenance_activity = None
@fields.depends(
'replacement', 'unit')
def on_change_replacement(self):
if not self.replacement:
self.unit = None
return
if not self.unit:
self.unit = self.replacement.sale_uom
@fields.depends('maintenance_activity', 'quantity', 'unit')
def on_change_maintenance_activity(self):
if not self.maintenance_activity:
self.quantity = None
self.unit = None
return
self.quantity = 1
if not self.unit:
self.unit = self.maintenance_activity.sale_uom
class MaintenanceActivity(ModelView, ModelSQL):
'Maintenance Activitys'
__name__ = 'optical_equipment_maintenance.activity'
maintenance = fields.Many2One(
'optical_equipment.maintenance', 'Maintenance')
product = fields.Many2One(
'product.product', 'Product',
domain=[
('maintenance_activity', '=', True)]
)
class ChangePropietaryMaintenance(ModelView):
'Change of Propietary Equipment'
__name__ = 'optical_equipment.change_propietary_maintenance.form'
old_propietary = fields.Many2One(
'party.party', 'Old Propietary', states={'required': True}
)
maintenance_service = fields.Many2Many(
'optical_equipment_maintenance.service',
None,
None,
'Maintenance Service',
domain=[('propietary', '=', Eval('old_propietary'))],
depends=['old_propietary'],
)
new_propietary = fields.Many2One(
'party.party', 'New Propietary', states={'required': True}
)
new_address = fields.Many2One(
'party.address',
'New Address',
required=True,
domain=[('party', '=', Eval('new_propietary'))],
states={'required': True},
)
change_date = fields.Date('Change Date', readonly=True)
@classmethod
def default_change_date(cls):
pool = Pool()
Date = pool.get('ir.date')
return Date.today()
class NewPropietaryMaintenance(Wizard):
'Change Propietary'
__name__ = 'optical_equipment.change_propietary_maintenance'
start = StateView(
'optical_equipment.change_propietary_maintenance.form',
'optical_equipment.change_propietary_maintenance_view_form',
[
Button('Cancel', 'end', 'tryton-cancel'),
Button('Create', 'change_propietary', 'tryton-ok', default=True),
],
)
change_propietary = StateAction(
'optical_equipment.act_optical_equipment_form')
def do_change_propietary(self, action):
services = self.start.maintenance_service
new_propietary = self.start.new_propietary
new_address = self.start.new_address
for service in services:
service.propietary = new_propietary
service.propietary_address = new_address
service.save()
for maintenance in service.lines:
maintenance.propietary = new_propietary
maintenance.propietary_address = new_address
maintenance.save()
class MaintenanceServiceReport(CompanyReport):
__name__ = 'optical_equipment_maintenance.service'
@classmethod
def execute(cls, ids, data):
with Transaction().set_context(address_with_party=True):
return super(MaintenanceServiceReport, cls).execute(ids, data)
@classmethod
def get_context(cls, records, header, data):
pool = Pool()
Date = pool.get('ir.date')
context = super().get_context(records, header, data)
context['today'] = Date.today()
return context