trytondo-optical_equipment/maintenance.py
2022-10-04 01:44:02 -05:00

686 lines
26 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.transaction import Transaction
from trytond.pyson import Bool, Eval, If, Id
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
import math as mt
import numpy as np
from trytond.exceptions import UserError
class MaintenanceService(Workflow, ModelSQL, ModelView):
'Equipment Maintenance Service'
__name__ = 'optical_equipment_maintenance.service'
_states = {'readonly': If(Eval('state') != 'draft', True)}
code = fields.Char("Code", readonly=True, select=True)
reference = fields.Char("Reference", select=True,
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', select=True,
states={'readonly': True})
sale_origin = fields.Reference("Sale Origin", selection='get_origin', select=True,
states={'readonly': True})
company = fields.Many2One('company.company', "Company", readonly=True)
maintenance_type = fields.Selection([('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",
states={'readonly': If(Eval('state') != 'in_progress', True)})
estimated_agended = fields.DateTime("Date Maintenance", 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", states=_states)
technical = fields.Many2One('company.employee', "Technical", states=_states)
state = fields.Selection([('draft', "Draft"),
('agended', "Agended"),
('in_progress', "In Progress"),
('failed', "Failed"),
('finished', "Finished")
], "State", required=True, readonly=True, sort=True)
@classmethod
def __setup__(cls):
super(MaintenanceService, cls).__setup__()
cls._transitions = ({
('draft', 'agended'),
('agended', 'in_progress'),
('in_progress', 'finished'),
})
cls._buttons.update({
'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')
@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.line')
return [Sale.__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()
Sale = pool.get('optical_equipment.contract')
return [Sale.__name__]
@classmethod
def get_origin_contract(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 set_code(cls, maintenance):
pool = Pool()
Config = pool.get('optical_equipment.configuration')
config = Config(2)
if config.maintenance_sequence != 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
@Workflow.transition('in_progress')
def in_progress(cls, maintenances):
pass
@classmethod
@ModelView.button
@Workflow.transition('finished')
def finished(cls, maintenances):
pass
class Maintenance(Workflow, ModelSQL, ModelView):
'Equipment Maintenance'
__name__ = 'optical_equipment.maintenance'
service_maintenance = fields.Many2One('optical_equipment_maintenance.service', "Maintenance Service",
ondelete='CASCADE', select=True)
code = fields.Char(
"Code", select=True,states={'readonly': True })
maintenance_type = fields.Selection([('preventive', 'Preventive'),
('corrective', 'Corrective')
], "Maintenance Type")
state = fields.Selection([('draft', "Draft"),
('finished', "Finished")
], "State",required=True, readonly=True, sort=False)
company = fields.Many2One('company.company', "Company", readonly=True)
propietary = fields.Many2One('party.party', "Propietary",
depends=['service_maintenance'])
propietary_address = fields.Many2One('party.address', "Propietary Address",
domain=[('party', '=', Eval('propietary'))],
depends=['service_maintenance']
)
equipment = fields.Many2One('optical_equipment.equipment', "Equipment", required=True,
domain=[('propietary', '=', Eval('propietary'))],
depends=['service_maintenance'])
#when the maintenance is in agended status
diary = fields.One2Many('optical_equipment_maintenance.diary', 'diary')
#estimated_agended = fields.DateTime("Date Maintenance")
#state_agended = fields.Selection([('no_agenda', "No agenda"),
# ('agended', "Agended"),
# ('in_progress', "In progress"),
# ('finish', "Finish"),
# ('failed', "Failed")], "State Agenda")
#technical = fields.Many2One('company.employee', "Technical")
#Preventive maintenance
initial_operation = fields.Boolean("Verificiació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")
optical = fields.Boolean("Optical")
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},
depends=['equipment'])
lines_calibration = fields.One2Many('optical_equipment.maintenance.calibration_sample', 'maintenance', "Lines of Calibration")
maintenance_lines = fields.One2Many('optical_equipment.maintenance.line', 'maintenance', 'Lines')
"""
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') == None, True)},
depends=['itemperature_min'])
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') == None, True)},
depends=['moisture_min'])
"""
@classmethod
def __setup__(cls):
super(Maintenance, cls).__setup__()
cls._transitions.update({
('draft', 'finished')
})
cls._buttons.update({
'in_progress': {'invisible': Eval('state').in_(['draft', 'in_progress', 'finished'])},
})
@staticmethod
def default_company():
return Transaction().context.get('company')
@fields.depends('service_maintenance')
def on_change_service_maintenance(self):
self.propietary = self.service_maintenance.propietary
self.propietary_address = self.service_maintenance.propietary_address
@fields.depends('equipment', 'patterns_equipments')
def on_change_equipment(self):
if self.equipment and self.equipment.product.calibration:
self.patterns_equipments = self.equipment.product.k_pattern
else:
self.patterns_equipments = None
@classmethod
def default_initial_operation(cls):
return True
@classmethod
def default_check_equipment(cls):
return True
@classmethod
def default_check_electric_system(cls):
return True
@classmethod
def default_clean_int_ext(cls):
return True
@classmethod
def default_clean_eyes(cls):
return True
@classmethod
def default_optical(cls):
return True
@classmethod
def default_check_calibration(cls):
return True
@classmethod
def default_state(cls):
return 'draft'
@classmethod
def default_maintenance_type(cls):
return 'preventive'
@classmethod
def default_state_agended(cls):
return 'no_agenda'
@classmethod
@ModelView.button
@Workflow.transition('in_progress')
def in_progress(cls, maintenances):
pass
@classmethod
@ModelView.button
@Workflow.transition('finished')
def finished(cls, maintenances):
raise UserError(str("Esto es una prueba"))
pass
@classmethod
def view_attributes(cls):
return super(Maintenance, cls).view_attributes() + [
('//page[@id="preventive"]', 'states', {
'invisible': If(Eval('maintenance_type') != 'preventive', True),
}),
('//page[@id="corrective"]', 'states',{
'invisible': If(Eval('maintenance_type') != 'corrective', True),
})
]
class CreateContractInitial(ModelView, ModelSQL):
'Create Contract Inicial'
__name__ = 'optical_equipment_create.contract'
company = fields.Many2One(
'company.company', "Company", readonly=True, required=True, select=True,
states={
'readonly': (Eval('state') != 'draft') | Eval('party', True),
},help="Make the subscription belong to the company.")
party = fields.Many2One(
'party.party', "Party", required=True,
help="The party who subscribes.")
invoice_address = fields.Many2One('party.address', 'Invoice Address',
required=True, domain=[('party', '=', Eval('party'))])
payment_term = fields.Many2One('account.invoice.payment_term',
'Payment Term')
contact = fields.Many2One(
'party.contact_mechanism', "Contact", required=True,
domain=[('party', '=', Eval('party'))],
context={
'company': Eval('company', -1),
})
start_date = fields.Date("Start Date", required=True)
end_date = fields.Date("End Date",
domain=['OR',
('end_date', '>=', If(
Bool(Eval('start_date')),
Eval('start_date', datetime.date.min),
datetime.date.min)),
('end_date', '=', None),
])
@staticmethod
def default_company():
return Transaction().context.get('company')
@classmethod
def default_start_date(cls):
pool = Pool()
Date = pool.get('ir.date')
return Date.today()
@fields.depends('party')
def on_change_party(self):
pool = Pool()
Date = pool.get('ir.date')
if self.party:
self.invoice_address = self.party.address_get(type='invoice')
if self.party.client_type == "ips":
self.end_date = Date.today() + timedelta(days=365)
else:
self.end_date = Date.today() + timedelta(days=182)
class CreateContract(Wizard):
__name__ = 'optical_equipment.maintenance.contract'
start = StateView('optical_equipment_create.contract',
'optical_equipment.create_contract_view_form',[
Button('Cancel', 'end', 'tryton-cancel'),
Button('Create', 'create_contract', 'tryton-ok', default=True),
])
create_contract = StateAction('optical_equipment.act_contract_form')
@property
def _subscription_start(self):
return dict(
party=self.start.party,
contact=self.start.contact,
start_date=self.start.start_date,
end_date=self.start.end_date,
invoice_address=self.start.invoice_address
)
def _create_contract_base(self, dates, subscription):
pool = Pool()
ContractBase = pool.get('optical_equipment.contract')
a = self._subscription_start
contractBase = ContractBase(
state='draft',
party=a['party'],
invoice_address=a['invoice_address'],
start_date=a['start_date'],
end_date=a['end_date'],
contact=a['contact'],
equipments=a['equipments']
)
contractBase.save()
def do_create_contract(self, action):
maintenance_service = self.records[0]
pool = Pool()
Contract = pool.get('optical_equipment.contract')
dates = self._subscription_start
prorogues = (maintenance_service,)
contract = Contract(party=dates['party'],
invoice_address=dates['invoice_address'],
contact=dates['contact'],
start_date=dates['start_date'],
end_date=dates['end_date'],
maintenance_services=prorogues
)
contract.save()
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 AgendedInitial(ModelView):
'Agended maintenance service'
__name__ = 'optical_equipment_maintenance.agended'
maintenance_service = fields.Many2One('optical_equipment_maintenance.service',"Maintenaince Service",
required=True, domain=[('state', '=', 'draft')])
estimated_agended = fields.DateTime("Date Maintenance", required=True)
technical = fields.Many2One('company.employee', "Technical", required=True)
class AssingAgended(Wizard):
'Assing Agended'
__name__ = 'optical_equipment_maintenance.assing_agended'
start = StateView('optical_equipment_maintenance.agended',
'optical_equipment.assing_agended_view_form', [
Button('Cancel', 'end', 'tryton-cancel'),
Button('Assing', 'assing_agended', 'tryton-ok', default=True),
])
assing_agended = StateAction('optical_equipment.act_maintenance_service_form')
def do_assing_agended(self, action):
pool = Pool()
Diary = pool.get('optical_equipment_maintenance.diary')
Config = pool.get('optical_equipment.configuration')
config = Config(3)
MaintenanceService = pool.get('optical_equipment_maintenance.service')
diary = Diary(code=config.agended_sequence.get(),
maintenance_service=self.start.maintenance_service,
date_expected=self.start.estimated_agended,
date_estimated=self.start.estimated_agended + timedelta(days=15),
date_end=self.start.estimated_agended + timedelta(days=15),
technical=self.start.technical.id,
state='agended')
diary.save()
maintenanceService = self.start.maintenance_service
maintenanceService.estimated_agended = self.start.estimated_agended
maintenanceService.technical = self.start.technical
maintenanceService.state_agended = 'agended'
maintenanceService.state = 'agended'
maintenanceService.history_agended += (diary.id,)
maintenanceService.set_code(maintenanceService)
maintenanceService.save()
class ReAgended(ModelView):
'Agended maintenance service'
__name__ = 'optical_equipment_maintenance.reagended'
maintenance_service = fields.Many2One('optical_equipment_maintenance.service',"Maintenaince Service",
required=True, domain=[('state', '=', 'failed')])
estimated_agended = fields.DateTime("Date Maintenance", required=True)
technical = fields.Many2One('company.employee', "Technical", required=True)
class ReAssingAgended(Wizard):
'Assing Agended'
__name__ = 'optical_equipment_maintenance.reassing_agended'
start = StateView('optical_equipment_maintenance.reagended',
'optical_equipment.reassing_agended_view_form', [
Button('Cancel', 'end', 'tryton-cancel'),
Button('Assing', 'assing_agended', 'tryton-ok', default=True),
])
assing_agended = StateAction('optical_equipment.act_maintenance_service_form')
def do_assing_agended(self, action):
pool = Pool()
Diary = pool.get('optical_equipment_maintenance.diary')
diary = Diary(maintenance_service=self.start.maintenance_service,
date_expected=self.start.estimated_agended,
date_estimated=self.start.estimated_agended + timedelta(days=15),
date_end=self.start.estimated_agended + timedelta(days=15),
technical=self.start.technical.id,
state='agended')
diary.save()
maintenanceService = self.start.maintenance_service
maintenanceService.estimated_agended = self.start.estimated_agended
maintenanceService.technical = self.start.technical
maintenanceService.state_agended = 'agended'
maintenanceService.state = 'agended'
maintenanceService.history_agended += (diary.id,)
maintenanceService.save()
class ServiceMaintenanceAgended(ModelSQL):
'Service Maintenance - Agended'
__name__ = 'optical_equipment_maintenance.service-maintenance.diary'
maintenance_service = fields.Many2One('optical_equipment_maintenance.service', "Maintenance Service")
agended = fields.Many2One('optical_equipment_maintenance.diary', "Agended")
class MaintenanceLine(ModelSQL, ModelView):
'Maintenance Line'
__name__ = 'optical_equipment.maintenance.line'
product = fields.Many2One('product.product', 'Product',
ondelete='RESTRICT',domain=[
If(Eval('sale_state').in_(['draft']),
('maintenance_activity', '=', True),
()),
],)
maintenance = fields.Many2One('optical_equipment.maintenance', 'Maintenance', ondelete='CASCADE', select=True)
maintenance_activity = fields.Many2One('product.product', 'Maintenance activity')
class Calibration(ModelSQL, ModelView):
'Calibration of Maintenance'
__name__ = 'optical_equipment.maintenance.calibration'
maintenance = fields.Many2One('optical_equipment.maintenance', "Maintenance", ondelete="CASCADE",
select=True, required=True)
samples = fields.One2Many('optical_equipment.maintenance.calibration_sample', 'maintenance',
'Samples')
dev_std = fields.Function(
fields.Float("Standart Desviation"),'get_standard_deviation'
)
uncertain_type_A = fields.Function(
fields.Float("Uncertain Type A"), 'get_uncertain_A'
)
uncertain_pattern = fields.Function(
fields.Float("Uncertain Pattern"), 'get_uncertain_pattern'
)
k_c_calibration = fields.Function(
fields.Float("K Crt Calibration"), 'get_k_certificated_calibration'
)
uncertain_U_b1 = fields.Function(
fields.Float("U_b1"), 'get_uncertain_U_b1'
)
d_resolution = fields.Float("d_resolution")
uncertain_U_b2_dig = fields.Function(
fields.Float("U_b2"), 'get_uncertain_b2_digital'
)
uncertain_U_b2_ana = fields.Function(
fields.Float("U_b2"), 'get_uncertain_b2_analoga'
)
uncertain_combinated = fields.Function(
fields.Float("U_combinated"), 'get_uncertain_combinated'
)
uncertain_eff = fields.Function(
fields.Float("U eff"), 'get_uncertain_eff'
)
average = fields.Float("Average")
#total_samples total de muestras
#average_pattern_equipment #Promedio de las muestras tomadas en el equipo suma(value_equipment)/total_samples
#Desviacion estandar muestral != desviación estandar poblacional
def get_standard_deviation(self):
"""
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 sample) / (n_samples -1)
dev_std = mt.sqrt(dev_std_square)
return dev_std
def get_uncertain_type_A(self):
"""
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
class CalibrationSample(sequence_ordered(), ModelView, ModelSQL):
'Samples of Calibration'
__name__ = 'optical_equipment.maintenance.calibration_sample'
maintenance = fields.Many2One('optical_equipment.maintenance', 'Maintenance',
ondelete='CASCADE')
number_sample = fields.Float("Sample #")
value_patterns = fields.Many2One('optical_equipment.product_pattern', "Value Pattern", required=True,
ondelete='RESTRICT')
#value_pattern = fields.Float("Value in Pattern")
value_equipment = fields.Float("Value in Equipment", required=True,
states={'readonly': Eval('value_patterns') == None})
mistake = fields.Float("Mistake")
mistake_rate = fields.Float("% Mistake", states={'readonly': True},
depends=['mistake'])
@fields.depends('value_patterns', 'value_equipment', 'mistake', 'mistake_rate')
def on_change_value_equipment(self):
if float(self.value_patterns.pattern) < 0:
self.mistake = self.value_patterns.pattern - self.value_equipment
else:
if self.value_patterns.pattern > self.value_equipment:
self.mistake = self.value_patterns.pattern - self.value_equipment
else:
self.mistake = -self.value_patterns.pattern + self.value_equipment
self.mistake_rate = abs(self.mistake / self.value_patterns.pattern) * 100