trytondo-optical_equipment/maintenance.py

934 lines
38 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, Unique, fields, sequence_ordered)
from trytond.wizard import (
Button, StateAction, StateTransition, StateView, Wizard)
from trytond.modules.company import CompanyReport
from trytond.transaction import Transaction
from trytond.pyson import Bool, Eval, If, Id, Equal
from trytond.pool import Pool
from trytond.modules.currency.fields import Monetary
from trytond.modules.product import price_digits
import datetime
from datetime import timedelta
from scipy.stats import t
import matplotlib.pyplot as plt
import numpy as np
import math as mt
from io import BytesIO
from trytond.exceptions import UserError
_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': If(Eval('state') != 'draft', True)}
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',
states={'readonly': If(Eval('state') == 'finished', True)})
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", states={
'readonly': If(Eval('state') == 'finished', True),
'required': If(Eval('state') == 'in_progress', True)})
temperature_max = fields.Float("Temp Max", states={
'readonly': If(Eval('state') == 'finished', True),
'required': If(Eval('state') == 'in_progress', True)})
temperature_uom = fields.Many2One('product.uom', 'Temperature UOM',
domain=[
('category', '=', Id(
'optical_equipment', "uom_cat_temperature"))],
states={'invisible': If(Eval('temperature_min') is None, True),
'readonly': (Eval('state') == 'finished'),
'required': If(Eval('state') == 'in_progress', True)},)
moisture_min = fields.Float("Moisture Min", states={
'readonly': If(Eval('state') == 'finished', True),
'required': If(Eval('state') == 'in_progress', True)})
moisture_max = fields.Float("Moisture Max", states={
'readonly': If(Eval('state') == 'finished', True),
'required': If(Eval('state') == 'in_progress', True)})
moisture_uom = fields.Many2One('product.uom', "Moisture UOM",
domain=[
('category', '=', Id(
'optical_equipment', 'uom_cat_relative_humedity'))],
states={'invisible': If(Eval('moisture_min') is None, True),
'readonly': Eval('state') == 'finished',
'required': If(Eval('state') == 'in_progress', True)},)
@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)
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)
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 _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):
for maintenance in maintenances:
maintenance.current_agended.state = 'in_progress'
maintenance.current_agended.save()
@classmethod
@ModelView.button
@Workflow.transition('finished')
def finished(cls, maintenances):
for maintenance in maintenances:
maintenance.current_agended.state = 'finished'
maintenance.current_agended.save()
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})
# when the maintenance is in agended status
diary = fields.One2Many('optical_equipment_maintenance.diary', 'diary')
# 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"))],
states={'invisible': If(Eval('temperature_min') is None, True),
'readonly': (Eval('state') == 'finished')},)
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'))],
states={'invisible': If(Eval('moisture_min') is None, True),
'readonly': Eval('state') == 'finished'},)
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')
@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 __setup__(cls):
super(MaintenanceServiceLine, cls).__setup__()
cls._transitions.update({
('draft', 'finished')
})
cls._buttons.update({
'in_progress': {'invisible': Eval('state').in_(['draft', 'in_progress', 'finished'])},
'finished': {'invisible': (Eval('state').in_(['finished'])) |
((Eval('maintenance_type') == 'corrective') & (Eval('maintenance_lines') == ()))},
'samples': {'invisible': (Eval('state').in_(['finished'])) | (Eval('lines_calibration') != ()) | (~Eval('equipment_calibrate'))},
'calibrate': {'invisible': (Eval('lines_calibration') == ()) | (Eval('state').in_(['finished'])),
'depends': ['state'], }
})
@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'),
})
]
@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 default_state_agended(cls):
return 'no_agenda'
@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('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:
self.patterns_equipments = self.equipment.product.k_pattern
self.equipment_calibrate = self.equipment.product.calibration
self.initial_operation = self.equipment.product.initial_operation
self.check_equipment = self.equipment.product.check_equipment
self.check_electric_system = self.equipment.product.check_electric_system
self.clean_int_ext = self.equipment.product.clean_int_ext
self.clean_eyes = self.equipment.product.clean_eyes
self.check_calibration = self.equipment.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_uncertain_pattern(self):
"""
uncertain_pattern = 0,25 constante viene del equipo
"""
uncertain_pattern = 0.25
return uncertain_pattern
def get_k_certificated_calibration(self):
k_certificated_calibration = 2
return k_certicated_calibration
def get_uncertain_U_b1(self):
uncertain_b1 = MEP / mt.sqrt(3)
uncertain_b1a = uncertain_pattern / k_certificated_calibration
return uncertain_b1
def default_d_resolution(self):
return d
def get_uncertain_b2_digital(self):
uncertain_b2 = d / 2 * mt.sqrt(3)
return uncertain_b2
def get_uncertain_b2_analog(self):
"""
Incertidumbre por resolución Análoga
a contante que viene del equipo
"""
uncertain_b2_analog = d / a * math.sqrt(3)
return uncertain_b2_analog
def get_uncertain_combinated(self):
"""
Incertidumbre Combinada
"""
sum_uncertain_c = uncertain_type_A**2 + uncertain_b1**2 + uncertain_b2**2
uncertain_c = math.sqrt(sum_uncertain_c)
return uncertain_c
def get_uncertain_eff(self):
"""
Grados Efectivos de libertad
"""
uncertain_eff = uncertain_c**4 / \
((uncertain_type_A**4) / (len(sample) - 1) +
(uncertain_b1**4 / U_subi) + (uncertain_b2**4 / U_subi))
return uncertain_eff
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)")
else:
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:
samples = dates[pattern]
mean = sum(samples) / len(samples)
U_subi = maintenance.equipment.product.Usubi
uncertain_pattern = maintenance.equipment.product.uncertainy_pattern
MEP = maintenance.equipment.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
uncertain_b1a = uncertain_pattern / k_certificated_calibration # Ub1_MEP
if maintenance.equipment.product.resolution_type == "analoga":
a_resolution = maintenance.equipment.product.analog_resolution
resolution = a_resolution
factor_a = maintenance.equipment.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 maintenance.equipment.product.resolution_type == "digital":
d_resolution = maintenance.equipment.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 maintenance.equipment.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 maintenance.equipment.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()
equipment_risk = maintenance.equipment.product.risk
image = cls.get_create_graph(
dates_mistake_pattern, patterns, resolution, equipment_risk)
maintenance.graph_calibration = image
maintenance.save()
class MaintenanceLine(ModelSQL, ModelView):
'Maintenance Line'
__name__ = 'optical_equipment.maintenance.line'
line_replace = fields.Boolean(
"Replace",
states={
'readonly': If(
Eval('line_maintenance_activity') == True,
True)})
line_maintenance_activity = fields.Boolean(
"Maintenance Activity", states={
'readonly': If(
Eval('line_replace') == True, True)})
maintenance = fields.Many2One(
'optical_equipment.maintenance',
'Maintenance',
ondelete='CASCADE',
)
replacement = fields.Many2One('product.product', 'Replacement', ondelete='RESTRICT',
domain=[('replacement', '=', True)],
states={'invisible': (If(Eval('line_maintenance_activity') == True, True)) | (If(Eval('line_replace') == False, True)),
'required': If(Eval('line_replace') == True, True)},
depends={'line_replace'})
maintenance_activity = fields.Many2One('product.product', 'Maintenance activity',
domain=[('maintenance_activity', '=', True)],
states={'invisible': If(Eval('line_replace') == True, True) |
(If(Eval('line_maintenance_activity') == False, True)),
'required': If(Eval('line_maintenance_actitvity') == True, 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('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 self.line_replace == False:
self.replacement = None
@fields.depends('line_maintenance_activity', 'maintenance_activity')
def on_change_line_maintenance_activity(self, name=None):
if self.line_maintenance_activity == False:
self.maintenance_activity = None
@fields.depends('replacement', 'maintenance', 'unit', 'maintenance')
def on_change_replacement(self):
if not self.replacement:
self.unit = None
return
if not self.unit or self.unit.category != category:
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 or self.unit.category != category:
self.unit = self.maintenance_activity.sale_uom
class MaintenanceActivity(ModelView, ModelSQL):
'Maintenance Activitys'
__name__ = 'optical_equipment_maintenance.activity'
maintenance = fields.Many2One('optical_equipment.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):
old_propietary = self.start.old_propietary
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