commit
0aace73d54
@ -1,4 +1,4 @@
|
||||
Copyright (C) 2022 trytondo-smart-vision
|
||||
Copyright (C) 2023
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -2,4 +2,5 @@ include CHANGELOG
|
||||
include COPYRIGHT
|
||||
include LICENSE
|
||||
include README.rst
|
||||
include icons/LICENSE
|
||||
graft doc
|
||||
|
66
__init__.py
66
__init__.py
@ -1,17 +1,71 @@
|
||||
# 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.pool import Pool
|
||||
from . import (party, product, purchase, sale,
|
||||
equipment, subscription, measurements)
|
||||
from . import (agended, balance_sale_party, calibration, configuration, contract, diary,
|
||||
equipment, party, product, maintenance, move, purchase, sale)
|
||||
|
||||
__all__ = ['register']
|
||||
|
||||
|
||||
def register():
|
||||
Pool.register(
|
||||
equipment.OpticalEquipment,
|
||||
equipment.EquipmentMaintenance,
|
||||
equipment.EquipmentContract,
|
||||
equipment.EquipmentParty,
|
||||
equipment.ChangePropietary,
|
||||
equipment.ChangeEquipment,
|
||||
agended.AgendedInitial,
|
||||
agended.ReAgended,
|
||||
agended.ServiceMaintenanceAgended,
|
||||
calibration.Calibration,
|
||||
calibration.CalibrationSample,
|
||||
configuration.Configuration,
|
||||
diary.Diary,
|
||||
contract.Cron,
|
||||
contract.Contract,
|
||||
contract.ContractMaintenanceServices,
|
||||
contract.ContractEquipment,
|
||||
contract.CreateContractInitial,
|
||||
party.Address,
|
||||
party.Party,
|
||||
product.Template,
|
||||
product.Product,
|
||||
product.Pattern,
|
||||
product.UsePattern,
|
||||
product.Image,
|
||||
purchase.Purchase,
|
||||
purchase.Line,
|
||||
sale.Sale,
|
||||
sale.SaleDate,
|
||||
sale.SaleLine,
|
||||
equipment.OpticalEquipment,
|
||||
subscription.Subscription,
|
||||
subscription.SubscriptionEquipment,
|
||||
measurements.Measurements,
|
||||
balance_sale_party.BalanceSalePartyStart,
|
||||
maintenance.MaintenanceService,
|
||||
maintenance.MaintenanceServiceLine,
|
||||
maintenance.MaintenanceLine,
|
||||
maintenance.MaintenanceActivity,
|
||||
maintenance.ChangePropietaryMaintenance,
|
||||
move.Move,
|
||||
move.ShipmentOut,
|
||||
move.ShipmentInternal,
|
||||
move.ShipmentOutReturn,
|
||||
balance_sale_party.BalanceSalePartyStart,
|
||||
module='optical_equipment', type_='model')
|
||||
Pool.register(
|
||||
agended.AssingAgended,
|
||||
agended.ReAssingAgended,
|
||||
contract.CreateContract,
|
||||
equipment.NewPropietary,
|
||||
maintenance.NewPropietaryMaintenance,
|
||||
balance_sale_party.PrintBalanceSaleParty,
|
||||
sale.ConfirmSaleDate,
|
||||
module='optical_equipment', type_='wizard')
|
||||
Pool.register(
|
||||
calibration.CalibrationReport,
|
||||
contract.ContractReport,
|
||||
equipment.EquipmentReport,
|
||||
maintenance.MaintenanceServiceReport,
|
||||
move.PickingListDeliveryReport,
|
||||
move.CapacitationReport,
|
||||
balance_sale_party.BalanceSaleParty,
|
||||
module='optical_equipment', type_='report')
|
||||
|
125
agended.py
Normal file
125
agended.py
Normal file
@ -0,0 +1,125 @@
|
||||
# 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 ModelSQL, ModelView, fields
|
||||
from trytond.wizard import (
|
||||
Button, StateAction, StateTransition, StateView, Wizard)
|
||||
from trytond.pool import Pool
|
||||
from trytond.exceptions import UserError
|
||||
|
||||
import datetime
|
||||
from datetime import timedelta
|
||||
|
||||
|
||||
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 default_start(self, fields):
|
||||
if len(self.records) > 0:
|
||||
default = {'maintenance_service': self.records[0].id}
|
||||
else:
|
||||
default = {'maintenance_service': None}
|
||||
return default
|
||||
|
||||
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.current_agended = diary.id
|
||||
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 default_start(self, fields):
|
||||
if len(self.records) > 0:
|
||||
default = {'maintenance_service': self.records[0].id}
|
||||
else:
|
||||
default = {'maintenance_service': None}
|
||||
return default
|
||||
|
||||
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")
|
33
agended.xml
Normal file
33
agended.xml
Normal file
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tryton>
|
||||
<data>
|
||||
<record model="ir.ui.view" id="assing_agended_view_form">
|
||||
<field name="model">optical_equipment_maintenance.agended</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">assing_agended_form</field>
|
||||
</record>
|
||||
<record model="ir.action.wizard" id="act_assing_agended">
|
||||
<field name="name">Assing Agended</field>
|
||||
<field name="wiz_name">optical_equipment_maintenance.assing_agended</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="reassing_agended_view_form">
|
||||
<field name="model">optical_equipment_maintenance.reagended</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">reassing_agended_form</field>
|
||||
</record>
|
||||
<record model="ir.action.wizard" id="act_reassing_agended">
|
||||
<field name="name">ReAssing Agended</field>
|
||||
<field name="wiz_name">optical_equipment_maintenance.reassing_agended</field>
|
||||
</record>
|
||||
<menuitem parent="menu_diary"
|
||||
action="act_assing_agended"
|
||||
sequence="30"
|
||||
id="menu_assing_agended_form"/>
|
||||
<menuitem parent="menu_diary"
|
||||
action="act_reassing_agended"
|
||||
sequence="40"
|
||||
id="menu_reassing_agended_form"/>
|
||||
</data>
|
||||
</tryton>
|
147
balance_sale_party.py
Normal file
147
balance_sale_party.py
Normal file
@ -0,0 +1,147 @@
|
||||
# The COPYRIGHT file at the top level of this repository contains the full
|
||||
# copyright notices and license terms.
|
||||
from trytond.model import ModelView, fields
|
||||
from trytond.wizard import Wizard, StateView, Button, StateReport
|
||||
from trytond.report import Report
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
from trytond.transaction import Transaction
|
||||
from trytond.pyson import Eval
|
||||
from trytond.exceptions import UserError
|
||||
|
||||
__all__ = ['BalancePartyStart', 'PrintBalanceParty', 'BalanceParty']
|
||||
|
||||
class BalanceSalePartyStart(ModelView):
|
||||
'Balance Party Start'
|
||||
__name__ = 'optical_equipment.print_balance_sale_party.start'
|
||||
|
||||
party = fields.Many2One('party.party', 'Party', required=True)
|
||||
start_period = fields.Many2One('account.period', 'Start Period',
|
||||
domain=[
|
||||
('start_date', '<=', (Eval('end_period'), 'start_date')),
|
||||
], depends=['fiscalyear', 'end_period'])
|
||||
end_period = fields.Many2One('account.period', 'End Period',
|
||||
domain=[
|
||||
('start_date', '>=', (Eval('start_period'), 'start_date'))
|
||||
],
|
||||
depends=['start_period'])
|
||||
company = fields.Many2One('company.company', 'Company', required=True)
|
||||
party_type = fields.Selection([('out', 'Customer')], "Party Type", required=True)
|
||||
|
||||
@staticmethod
|
||||
def default_company():
|
||||
return Transaction().context.get('company')
|
||||
|
||||
@staticmethod
|
||||
def default_party_type():
|
||||
return 'out'
|
||||
|
||||
|
||||
class PrintBalanceSaleParty(Wizard):
|
||||
'Print Balance Sale Party'
|
||||
__name__ = 'optical_equipment.print_balance_sale_party'
|
||||
|
||||
start = StateView('optical_equipment.print_balance_sale_party.start',
|
||||
'optical_equipment.print_balance_sale_party_start_view_form', [
|
||||
Button('Cancel', 'end', 'tryton-cancel'),
|
||||
Button('Print', 'print_', 'tryton-print', default=True),
|
||||
])
|
||||
|
||||
print_ = StateReport('optical_equipment.balance_sale_party')
|
||||
|
||||
def default_start(self, fields):
|
||||
if len(self.records) > 0:
|
||||
default = {'party': self.records[0].party.id}
|
||||
else:
|
||||
default = {'party': None}
|
||||
return default
|
||||
|
||||
def do_print_(self, action):
|
||||
party = None
|
||||
party_type = None
|
||||
|
||||
if self.start.party:
|
||||
party = self.start.party.id
|
||||
if self.start.party_type:
|
||||
party_type = self.start.party_type
|
||||
|
||||
data = {
|
||||
'company': self.start.company.id,
|
||||
'party': party,
|
||||
'party_type': party_type,
|
||||
'start_period': self.start.start_period.id if self.start.start_period else None,
|
||||
'end_period' : self.start.end_period.id if self.start.end_period else None
|
||||
}
|
||||
return action, data
|
||||
|
||||
def transition_print_(self):
|
||||
return 'end'
|
||||
|
||||
|
||||
class BalanceSaleParty(Report):
|
||||
__name__ = 'optical_equipment.balance_sale_party'
|
||||
|
||||
@classmethod
|
||||
def get_context(cls, records, header, data):
|
||||
report_context = super(BalanceSaleParty, cls).get_context(records, header, data)
|
||||
pool = Pool()
|
||||
Company = pool.get('company.company')
|
||||
Period = pool.get('account.period')
|
||||
Sale = pool.get('sale.sale')
|
||||
Party = pool.get('party.party')
|
||||
start_period = None
|
||||
end_period = None
|
||||
party = None
|
||||
company = Company(data['company'])
|
||||
dom_sale = [('state', 'in', ["processing", "done"])]
|
||||
|
||||
if data.get('party'):
|
||||
party = data['party']
|
||||
dom_sale.append(('party', '=', party))
|
||||
|
||||
if data.get('start_period'):
|
||||
start_period = Period(data['start_period'])
|
||||
dom_sale.append(('sale_date', '>=', start_period.start_date))
|
||||
if data.get('end_period'):
|
||||
end_period = Period(data['end_period'])
|
||||
dom_sale.append(('sale_date', '<=', end_period.start_date))
|
||||
|
||||
sales = Sale.search(dom_sale,
|
||||
order=[('sale_date', 'DESC'),
|
||||
('id', 'DESC')],)
|
||||
|
||||
res = {}
|
||||
dict_location = {}
|
||||
|
||||
id_ = party
|
||||
party_ = Party.search(['id', '=', party])[0]
|
||||
name = party_.rec_name
|
||||
|
||||
try:
|
||||
if party_.identifiers:
|
||||
id_number = party_.identifiers[0].code
|
||||
else:
|
||||
id_number = ''
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
res[id_] = {'name': name,
|
||||
'id_number': id_number,
|
||||
'party': party_
|
||||
}
|
||||
|
||||
if sales:
|
||||
res[id_]['sales'] = sales
|
||||
else:
|
||||
raise UserError(str("Este Tercero no Cuenta Con Ventas en Proceso ó Confirmadas."))
|
||||
|
||||
report_context['records'] = res.values()
|
||||
report_context['start_period'] = start_period.name if start_period else '*'
|
||||
report_context['end_period'] = end_period.name if end_period else '*'
|
||||
report_context['company'] = company
|
||||
|
||||
residual_amount = 0
|
||||
for sale in sales:
|
||||
residual_amount += sale.residual_amount
|
||||
report_context['residual_amount'] = residual_amount
|
||||
|
||||
return report_context
|
28
balance_sale_party.xml
Normal file
28
balance_sale_party.xml
Normal file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tryton>
|
||||
<data>
|
||||
<record model="ir.action.report" id="report_balance_sale_party">
|
||||
<field name="name">Balance by Party</field>
|
||||
<field name="model"></field>
|
||||
<field name="report_name">optical_equipment.balance_sale_party</field>
|
||||
<field name="report">optical_equipment/report/balance_sale_party.fods</field>
|
||||
<field name="template_extension">ods</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="print_balance_sale_party_start_view_form">
|
||||
<field name="model">optical_equipment.print_balance_sale_party.start</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">print_balance_sale_party_start_form</field>
|
||||
</record>
|
||||
<record model="ir.action.wizard" id="wizard_print_balance_sale_party">
|
||||
<field name="name">Print Balance Sale by Party</field>
|
||||
<field name="wiz_name">optical_equipment.print_balance_sale_party</field>
|
||||
</record>
|
||||
<menuitem
|
||||
parent="sale.menu_reporting"
|
||||
action="wizard_print_balance_sale_party"
|
||||
id="menu_print_balance_sale_party"
|
||||
icon="tryton-print"/>
|
||||
</data>
|
||||
</tryton>
|
94
calibration.py
Normal file
94
calibration.py
Normal file
@ -0,0 +1,94 @@
|
||||
# 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, sequence_ordered)
|
||||
from trytond.pyson import Bool, Eval, If, Id, Equal
|
||||
from trytond.pool import Pool
|
||||
from trytond.modules.company import CompanyReport
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
_digits = (16, 2)
|
||||
_states = {'readonly': If(Eval('state') != 'draft', True)}
|
||||
|
||||
class Calibration(ModelSQL, ModelView):
|
||||
'Calibration of Maintenance'
|
||||
__name__ = 'optical_equipment.maintenance.calibration'
|
||||
|
||||
_states={'readonly': True}
|
||||
|
||||
maintenance = fields.Many2One('optical_equipment.maintenance', "Maintenance", ondelete="CASCADE",
|
||||
select=True, required=True)
|
||||
graph_dates = fields.Char("Graph Dates", readonly=True)
|
||||
diopter = fields.Float("Diopter", states=_states)
|
||||
mean = fields.Float("Mean", states=_states)
|
||||
dev_std = fields.Float("Standart Desviation", states=_states)
|
||||
uncertain_type_A = fields.Float("Uncertain Type A", states=_states)
|
||||
uncertain_pattern = fields.Float("Uncertain Pattern", states=_states)
|
||||
k_c_calibration = fields.Float("K Crt Calibration",states=_states)
|
||||
uncertain_U_b1 = fields.Float("U_b1", states=_states)
|
||||
d_resolution = fields.Float("d_resolution", states=_states)
|
||||
uncertain_U_b2_dig = fields.Float("U_b2", states=_states)
|
||||
uncertain_U_b2_ana = fields.Float("U_b2", states=_states)
|
||||
uncertain_combinated = fields.Float("U_combinated", states=_states)
|
||||
uncertain_eff = fields.Float("U eff", states=_states)
|
||||
t_student = fields.Float("T Student", states=_states)
|
||||
|
||||
uncertain_expanded = fields.Float("Uexpand", _digits, states=_states)
|
||||
|
||||
state = fields.Char('State')
|
||||
|
||||
class CalibrationSample(sequence_ordered(), ModelView, ModelSQL):
|
||||
'Samples of Calibration'
|
||||
__name__ = 'optical_equipment.maintenance.calibration_sample'
|
||||
|
||||
maintenance = fields.Many2One('optical_equipment.maintenance', 'Maintenance')
|
||||
product = fields.Function(fields.Integer("Product ID"), 'on_change_with_product')
|
||||
number_sample = fields.Float("Sample #", _digits)
|
||||
value_patterns = fields.Many2One('optical_equipment.product_pattern', "Value Pattern", ondelete='RESTRICT', required=True,
|
||||
domain=[('product', '=', Eval('product'))],
|
||||
depends=['product'])
|
||||
value_equipment = fields.Float("Value in Equipment", _digits, required=True,
|
||||
states={'readonly': Eval('value_patterns') == None})
|
||||
mistake = fields.Float("Mistake", _digits)
|
||||
mistake_rate = fields.Float("% Mistake", _digits,
|
||||
states={'readonly': True},
|
||||
depends=['mistake'])
|
||||
|
||||
@fields.depends('maintenance', '_parent_maintenance.equipment')
|
||||
def on_change_with_product(self, name=None):
|
||||
if self.maintenance:
|
||||
return self.maintenance.equipment.product.template.id
|
||||
|
||||
@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
|
||||
|
||||
if self.value_patterns.pattern == self.value_equipment:
|
||||
self.mistake_rate = 0
|
||||
else:
|
||||
self.mistake_rate = abs(self.mistake / self.value_patterns.pattern) * 100
|
||||
|
||||
|
||||
class CalibrationReport(CompanyReport):
|
||||
__name__ = 'optical_equipment.maintenance'
|
||||
|
||||
@classmethod
|
||||
def execute(cls, ids, data):
|
||||
with Transaction().set_context(address_with_party=True):
|
||||
return super(CalibrationReport, 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
|
52
calibration.xml
Normal file
52
calibration.xml
Normal file
@ -0,0 +1,52 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tryton>
|
||||
<data>
|
||||
<record model="ir.ui.view" id="maintenance_calibration_view_form">
|
||||
<field name="model">optical_equipment.maintenance.calibration_sample</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">maintenance_sample_form</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="maintenance_calibration_view_tree">
|
||||
<field name="model">optical_equipment.maintenance.calibration_sample</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority" eval="10"/>
|
||||
<field name="name">maintenance_calibration_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="calibration_total_view_tree">
|
||||
<field name="model">optical_equipment.maintenance.calibration</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="name">calibration_total_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="calibration_total_view_form">
|
||||
<field name="model">optical_equipment.maintenance.calibration</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">calibration_total_form</field>
|
||||
</record>
|
||||
<record model="ir.action.report" id="report_calibration">
|
||||
<field name="name">Calibration</field>
|
||||
<field name="model">optical_equipment.maintenance</field>
|
||||
<field name="report_name">optical_equipment.maintenance</field>
|
||||
<field name="report">optical_equipment/report/Calibration.fodt</field>
|
||||
<field name="single" eval="True"/>
|
||||
</record>
|
||||
<record model="ir.action.keyword" id="report_calibration_keyword">
|
||||
<field name="keyword">form_print</field>
|
||||
<field name="model">optical_equipment.maintenance,-1</field>
|
||||
<field name="action" ref="report_calibration"/>
|
||||
</record>
|
||||
<record model="ir.action.report" id="report_calibrations">
|
||||
<field name="name">Calibrations</field>
|
||||
<field name="model">optical_equipment_maintenance.service</field>
|
||||
<field name="report_name">optical_equipment_maintenance.service</field>
|
||||
<field name="report">optical_equipment/report/Calibrations.fodt</field>
|
||||
<field name="single" eval="True"/>
|
||||
</record>
|
||||
<record model="ir.action.keyword" id="report_calibrations_keyword">
|
||||
<field name="keyword">form_print</field>
|
||||
<field name="model">optical_equipment_maintenance.service,-1</field>
|
||||
<field name="action" ref="report_calibrations"/>
|
||||
</record>
|
||||
</data>
|
||||
</tryton>
|
33
configuration.py
Normal file
33
configuration.py
Normal file
@ -0,0 +1,33 @@
|
||||
from trytond.model import (
|
||||
ModelSingleton, ModelSQL, ModelView, fields)
|
||||
from trytond.pyson import Id
|
||||
from trytond.modules.company.model import (
|
||||
CompanyMultiValueMixin, CompanyValueMixin)
|
||||
|
||||
|
||||
class Configuration(ModelSingleton, ModelSQL, ModelView, CompanyMultiValueMixin):
|
||||
'Equipment Configuration'
|
||||
__name__='optical_equipment.configuration'
|
||||
|
||||
equipment_sequence = fields.Many2One('ir.sequence', "Equipment Sequence",
|
||||
domain=[('sequence_type', '=', Id('optical_equipment', 'sequence_type_equipment'))])
|
||||
maintenance_sequence = fields.Many2One('ir.sequence', "Maintenance Sequence",
|
||||
domain=[('sequence_type', '=', Id('optical_equipment', 'sequence_type_maintenances'))])
|
||||
agended_sequence = fields.Many2One('ir.sequence', "Agended Sequence",
|
||||
domain=[('sequence_type', '=', Id('optical_equipment', 'sequence_type_agended'))])
|
||||
contract_sequence = fields.Many2One('ir.sequence', "Contract Sequence",
|
||||
domain=[('sequence_type', '=', Id('optical_equipment', 'sequence_type_contract'))])
|
||||
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"))],
|
||||
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'))],
|
||||
depends={'moisture_min'})
|
||||
sale_quote_number = fields.Many2One('ir.sequence', "Sale Quote Number",
|
||||
domain=[
|
||||
('sequence_type', '=', Id('sale','sequence_type_sale'))
|
||||
])
|
81
configuration.xml
Normal file
81
configuration.xml
Normal file
@ -0,0 +1,81 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tryton>
|
||||
<data>
|
||||
<record model="ir.action.act_window" id="act_optical_equipment_configuration_form">
|
||||
<field name="name">Configuration</field>
|
||||
<field name="res_model">optical_equipment.configuration</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="optical_equipment_configuration_view_form">
|
||||
<field name="model">optical_equipment.configuration</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">configuration_form</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_optical_equipment_configuration_form_view1">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view" ref="optical_equipment_configuration_view_form"/>
|
||||
<field name="act_window" ref="act_optical_equipment_configuration_form"/>
|
||||
</record>
|
||||
<menuitem
|
||||
name="Configuration"
|
||||
parent="menu_equipment"
|
||||
sequence="0"
|
||||
id="menu_equipment_configuration"
|
||||
icon="tryton-settings"/>
|
||||
<menuitem
|
||||
parent="menu_equipment_configuration"
|
||||
action="act_optical_equipment_configuration_form"
|
||||
sequence="10"
|
||||
id="menu_optical_equipment_configuration"
|
||||
icon="tryton-list"/>
|
||||
|
||||
<record model="res.group" id="group_maintenance_admin">
|
||||
<field name="name">Maintenance Administration</field>
|
||||
</record>
|
||||
<record model="res.user-res.group"
|
||||
id="user_admin_group_maintenance_admin">
|
||||
<field name="user" ref="res.user_admin"/>
|
||||
<field name="group" ref="group_maintenance_admin"/>
|
||||
</record>
|
||||
<record model="ir.ui.menu-res.group"
|
||||
id="menu_party_group_equipment_admin">
|
||||
<field name="menu" ref="menu_equipment"/>
|
||||
<field name="group" ref="group_equipment_admin"/>
|
||||
</record>
|
||||
<record model="ir.sequence.type" id="sequence_type_equipment">
|
||||
<field name="name">Equipment</field>
|
||||
</record>
|
||||
<record model="ir.sequence.type-res.group"
|
||||
id="sequence_type_equipment_group_admin">
|
||||
<field name="sequence_type" ref="sequence_type_equipment"/>
|
||||
<field name="group" ref="res.group_admin"/>
|
||||
</record>
|
||||
<record model="ir.sequence.type-res.group"
|
||||
id="sequence_type_equipment_group_equipment_admin">
|
||||
<field name="sequence_type" ref="sequence_type_equipment"/>
|
||||
<field name="group" ref="group_equipment_admin"/>
|
||||
</record>
|
||||
<record model="ir.sequence" id="sequence_equipment">
|
||||
<field name="name">Equipment</field>
|
||||
<field name="sequence_type" ref="sequence_type_equipment"/>
|
||||
</record>
|
||||
<record model="ir.sequence.type" id="sequence_type_maintenances">
|
||||
<field name="name">Maintenances</field>
|
||||
</record>
|
||||
<record model="ir.sequence.type-res.group"
|
||||
id="sequence_type_maintenance_group_admin">
|
||||
<field name="sequence_type" ref="sequence_type_maintenances"/>
|
||||
<field name="group" ref="res.group_admin"/>
|
||||
</record>
|
||||
<record model="ir.sequence.type-res.group"
|
||||
id="sequence_type_maintenance_group_maintenance_admin">
|
||||
<field name="sequence_type" ref="sequence_type_maintenances"/>
|
||||
<field name="group" ref="group_maintenance_admin"/>
|
||||
</record>
|
||||
<record model="ir.sequence" id="sequence_maintenances">
|
||||
<field name="name">Maintenance</field>
|
||||
<field name="sequence_type" ref="sequence_type_maintenances"/>
|
||||
</record>
|
||||
</data>
|
||||
</tryton>
|
358
contract.py
Normal file
358
contract.py
Normal file
@ -0,0 +1,358 @@
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
from trytond.model import (
|
||||
ModelSQL, ModelView, Workflow, fields)
|
||||
from trytond.modules.company import CompanyReport
|
||||
from trytond.pyson import Eval, If, Bool
|
||||
from trytond.modules.company.model import set_employee
|
||||
from trytond.exceptions import UserError
|
||||
from trytond.transaction import Transaction
|
||||
from trytond.wizard import (
|
||||
Button, StateAction, StateTransition, StateView, Wizard)
|
||||
|
||||
from trytond.modules.currency.fields import Monetary
|
||||
from trytond.modules.product import price_digits
|
||||
|
||||
import datetime
|
||||
from datetime import timedelta, date
|
||||
|
||||
class Cron(metaclass=PoolMeta):
|
||||
__name__ = 'ir.cron'
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super().__setup__()
|
||||
cls.method.selection.append(
|
||||
('optical_equipment.contract|contract_expiration', 'Contract Expiration'),
|
||||
)
|
||||
|
||||
|
||||
class Contract(Workflow, ModelSQL, ModelView):
|
||||
'Contracts'
|
||||
__name__ = 'optical_equipment.contract'
|
||||
_rec_name = 'number'
|
||||
_order_name = 'number'
|
||||
|
||||
|
||||
company = fields.Many2One(
|
||||
'company.company', "Company", required=True, select=True,
|
||||
states={
|
||||
'readonly': (Eval('state') != 'draft') | Eval('party', True),
|
||||
},help="Make the subscription belong to the company.")
|
||||
number = fields.Char(
|
||||
"Number", readonly=True, select=True,
|
||||
help="The main identification of the subscription.")
|
||||
reference = fields.Char(
|
||||
"Reference", select=True,
|
||||
help="The identification of an external origin.")
|
||||
description = fields.Char("Description",
|
||||
states={
|
||||
'readonly': Eval('state') != 'draft',
|
||||
})
|
||||
party = fields.Many2One(
|
||||
'party.party', "Party", required=True,
|
||||
states={
|
||||
'readonly': (Eval('state') != 'draft') | Eval('party', True),
|
||||
},help="The party who subscribes.")
|
||||
contact = fields.Many2One('party.contact_mechanism', "Contact", required=True)
|
||||
invoice_address = fields.Many2One('party.address', 'Invoice Address',
|
||||
required=True, domain=[('party', '=', Eval('party'))],
|
||||
states={
|
||||
'readonly': (Eval('state') != 'draft') | Eval('party', True),
|
||||
})
|
||||
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),
|
||||
],
|
||||
states={
|
||||
'readonly': Eval('state') != 'draft',
|
||||
})
|
||||
maintenance_services = fields.Many2Many('optical_equipment_maintenance.service-equipment.contract',
|
||||
'contract', 'maintenance_services', "Prorogues",
|
||||
states={'readonly': Eval('state') != 'draft'})
|
||||
equipments = fields.One2Many('optical_equipment.equipment', 'contract', "Equipments",
|
||||
states={'readonly': Eval('state') != 'draft'})
|
||||
price_contract = Monetary("Price Contract", digits=price_digits, currency='currency', required=True,
|
||||
states={'readonly': Eval('state') != 'draft'})
|
||||
state = fields.Selection([
|
||||
('draft', "Draft"),
|
||||
('running', "Running"),
|
||||
('closed', "Closed"),
|
||||
('cancelled', "Cancelled"),
|
||||
], "State", readonly=True, required=False, sort=False,
|
||||
help="The current state of the subscription.")
|
||||
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(Contract, cls).__setup__()
|
||||
cls._order = [
|
||||
('number', 'DESC NULLS FIRST'),
|
||||
('id', 'DESC'),
|
||||
]
|
||||
cls._transitions = ({
|
||||
('draft', 'running'),
|
||||
('running', 'draft'),
|
||||
('running', 'closed'),
|
||||
('running', 'cancelled'),
|
||||
})
|
||||
cls._buttons.update({
|
||||
'draft': {'invisible': Eval('state').in_(['draft','closed'])},
|
||||
'running': {'invisible': Eval('state').in_(['cancelled', 'running'])},
|
||||
'closed': {'invisible': True},
|
||||
'cancelled': {'invisible': Eval('state').in_(['draft', 'cancelled'])}
|
||||
})
|
||||
|
||||
|
||||
@staticmethod
|
||||
def default_company():
|
||||
return Transaction().context.get('company')
|
||||
|
||||
@staticmethod
|
||||
def default_state():
|
||||
return 'draft'
|
||||
|
||||
@classmethod
|
||||
def set_number(cls, contracts):
|
||||
pool = Pool()
|
||||
Config = pool.get('optical_equipment.configuration')
|
||||
config = Config(4)
|
||||
|
||||
if config.contract_sequence != None:
|
||||
if not contracts[0].number:
|
||||
try:
|
||||
contracts[0].number = config.contract_sequence.get()
|
||||
cls.save(contracts)
|
||||
except UserError:
|
||||
raise UserError(str('Validation Error'))
|
||||
else:
|
||||
raise UserError(gettext('optical_equipment.msg_not_sequence_equipment'))
|
||||
|
||||
@classmethod
|
||||
def contract_expiration(cls):
|
||||
pool = Pool()
|
||||
Contracts = pool.get('optical_equipment.contract')
|
||||
|
||||
contracts_to_expire = cls.search([('state', '=', 'running'),
|
||||
('end_date', '<=', date.today())])
|
||||
|
||||
if contracts_to_expire != []:
|
||||
for contract in contracts_to_expire:
|
||||
cls.closed([contract])
|
||||
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
@Workflow.transition('draft')
|
||||
def draft(cls, contracts):
|
||||
contract = contracts[0]
|
||||
contract.state = 'closed'
|
||||
for equipment in contract.equipments:
|
||||
equipment.state = "uncontrated"
|
||||
equipment.contract_history += (contract.id,)
|
||||
equipment.save()
|
||||
contract.save()
|
||||
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
@Workflow.transition('closed')
|
||||
def closed(cls, contracts):
|
||||
contract = contracts[0]
|
||||
for equipment in contract.equipments:
|
||||
equipment.state = "uncontrated"
|
||||
equipment.save()
|
||||
|
||||
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
@Workflow.transition('running')
|
||||
def running(cls, contracts):
|
||||
contract = contracts[0]
|
||||
for equipment in contract.equipments:
|
||||
equipment.state = "contrated"
|
||||
equipment.contract_history += (contract.id,)
|
||||
equipment.save()
|
||||
|
||||
cls.set_number(contracts)
|
||||
contract.state='running'
|
||||
contract.save()
|
||||
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
@Workflow.transition('cancelled')
|
||||
def cancelled(cls, contracts):
|
||||
contract = contracts[0]
|
||||
for equipment in contract.equipments:
|
||||
equipment.state = "uncontrated"
|
||||
equipment.save()
|
||||
|
||||
|
||||
class ContractMaintenanceServices(ModelSQL):
|
||||
'Contract - Maintenance Services'
|
||||
__name__ = 'optical_equipment_maintenance.service-equipment.contract'
|
||||
|
||||
maintenance_services = fields.Many2One('optical_equipment_maintenance.service', "Maintenance Service", select=True)
|
||||
contract = fields.Many2One('optical_equipment.contract', "Contract")
|
||||
|
||||
|
||||
class ContractEquipment(ModelSQL):
|
||||
'Optical Equipment - Contract'
|
||||
__name__ = 'optical_equipment.contract-optical_equipment.equipment'
|
||||
|
||||
equipment = fields.Many2One('optical_equipment.equipment', 'Equipment', select=True)
|
||||
contract = fields.Many2One('optical_equipment.contract', 'Contract', select=True)
|
||||
|
||||
|
||||
class ContractReport(CompanyReport):
|
||||
__name__ = 'optical_equipment.contract'
|
||||
|
||||
@classmethod
|
||||
def execute(cls, ids, data):
|
||||
with Transaction().set_context(address_with_party=True):
|
||||
return super(ContractReport, 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
|
||||
|
||||
|
||||
class CreateContractInitial(ModelView, ModelSQL):
|
||||
'Create Contract Inicial'
|
||||
__name__ = 'optical_equipment_create.contract'
|
||||
|
||||
currency = fields.Many2One('currency.currency', 'Currency', required=True)
|
||||
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),
|
||||
])
|
||||
unit_price = Monetary("Unit Price", digits=price_digits, currency='currency', required=True)
|
||||
|
||||
@staticmethod
|
||||
def default_company():
|
||||
return Transaction().context.get('company')
|
||||
|
||||
@staticmethod
|
||||
def default_currency():
|
||||
Company = Pool().get('company.company')
|
||||
if Transaction().context.get('company'):
|
||||
company = Company(Transaction().context['company'])
|
||||
return company.currency.id
|
||||
|
||||
@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.customer_type == "ips":
|
||||
self.end_date = Date.today() + timedelta(days=182)
|
||||
else:
|
||||
self.end_date = Date.today() + timedelta(days=365)
|
||||
|
||||
|
||||
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')
|
||||
|
||||
|
||||
def default_start(self, fields):
|
||||
if self.record:
|
||||
default = {'party': self.record.propietary.id,
|
||||
'invoice_address': self.record.propietary_address.id,
|
||||
'unit_price': (self.record.sale_origin.amount
|
||||
if self.record.sale_origin.__name__ == "sale.line"
|
||||
else self.record.sale_origin.total_amount),
|
||||
}
|
||||
return default
|
||||
|
||||
@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,
|
||||
unit_price=self.start.unit_price
|
||||
)
|
||||
|
||||
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,)
|
||||
equipments = []
|
||||
for line in maintenance_service.lines:
|
||||
equipments.append(line.equipment.id)
|
||||
|
||||
if maintenance_service.contract_origin:
|
||||
contract=maintenance_service.contract_origin
|
||||
contract.invoice_address=dates['invoice_address']
|
||||
contract.contact=dates['contact']
|
||||
contract.start_date=dates['start_date']
|
||||
contract.end_date=dates['end_date']
|
||||
contract.maintenance_services+=prorogues
|
||||
contract.equipments=equipments
|
||||
contract.state='draft'
|
||||
contract.price_contract=dates['unit_price']
|
||||
#contract.price_contract=maintenance_service.sale_origin.sale.total_amount
|
||||
contract.save()
|
||||
else:
|
||||
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,
|
||||
equipments=equipments,
|
||||
state='draft',
|
||||
price_contract=dates['unit_price']
|
||||
)
|
||||
contract.save()
|
163
contract.xml
Normal file
163
contract.xml
Normal file
@ -0,0 +1,163 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tryton>
|
||||
<data>
|
||||
<record model="ir.ui.view" id="contract_view_form">
|
||||
<field name="model">optical_equipment.contract</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">contract_form</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="contract_view_list">
|
||||
<field name="model">optical_equipment.contract</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="name">contract_list</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window" id="act_contract_form">
|
||||
<field name="name">Contracts</field>
|
||||
<field name="res_model">optical_equipment.contract</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view"
|
||||
id="act_contract_form_view1">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view" ref="contract_view_list"/>
|
||||
<field name="act_window" ref="act_contract_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view"
|
||||
id="act_contract_form_view2">
|
||||
<field name="sequence" eval="20"/>
|
||||
<field name="view" ref="contract_view_form"/>
|
||||
<field name="act_window" ref="act_contract_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain"
|
||||
id="act_contract_form_domain_draft">
|
||||
<field name="name">Draft</field>
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="domain" eval="[('state', '=', 'draft')]" pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_contract_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain"
|
||||
id="act_contract_form_domain_running">
|
||||
<field name="name">Running</field>
|
||||
<field name="sequence" eval="30"/>
|
||||
<field name="domain" eval="[('state', '=', 'running')]" pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_contract_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain"
|
||||
id="act_contract_form_domain_closed">
|
||||
<field name="name">Closed</field>
|
||||
<field name="sequence" eval="40"/>
|
||||
<field name="domain" eval="[('state', '=', 'closed')]" pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_contract_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain"
|
||||
id="act_contract_form_domain_all">
|
||||
<field name="name">All</field>
|
||||
<field name="sequence" eval="9999"/>
|
||||
<field name="domain"></field>
|
||||
<field name="act_window" ref="act_contract_form"/>
|
||||
</record>
|
||||
<record model="ir.model.button" id="draft_running_button">
|
||||
<field name="name">draft</field>
|
||||
<field name="string">Draft</field>
|
||||
<field name="model" search="[('model', '=', 'optical_equipment.contract')]"/>
|
||||
</record>
|
||||
<record model="ir.model.button" id="contrac_running_button">
|
||||
<field name="name">running</field>
|
||||
<field name="string">Run</field>
|
||||
<field name="model" search="[('model', '=', 'optical_equipment.contract')]"/>
|
||||
</record>
|
||||
<record model="ir.model.button" id="contract_closed_button">
|
||||
<field name="name">closed</field>
|
||||
<field name="string">Closed</field>
|
||||
<field name="model" search="[('model', '=', 'optical_equipment.contract')]"/>
|
||||
</record>
|
||||
<record model="ir.model.button" id="contract_cancelled_button">
|
||||
<field name="name">cancelled</field>
|
||||
<field name="string">Cancel</field>
|
||||
<field name="model" search="[('model', '=', 'optical_equipment.contract')]"/>
|
||||
</record>
|
||||
<record model="res.group" id="group_contract_admin">
|
||||
<field name="name">Contract Administration</field>
|
||||
</record>
|
||||
<record model="res.user-res.group"
|
||||
id="user_admin_group_contract_admin">
|
||||
<field name="user" ref="res.user_admin"/>
|
||||
<field name="group" ref="group_contract_admin"/>
|
||||
</record>
|
||||
<record model="ir.sequence.type" id="sequence_type_contract">
|
||||
<field name="name">Contract</field>
|
||||
</record>
|
||||
<record model="ir.sequence.type-res.group"
|
||||
id="sequence_type_contract_group_admin">
|
||||
<field name="sequence_type" ref="sequence_type_contract"/>
|
||||
<field name="group" ref="res.group_admin"/>
|
||||
</record>
|
||||
<record model="ir.sequence.type-res.group"
|
||||
id="sequence_type_contract_group_contract_admin">
|
||||
<field name="sequence_type" ref="sequence_type_contract"/>
|
||||
<field name="group" ref="group_contract_admin"/>
|
||||
</record>
|
||||
<record model="ir.sequence" id="sequence_contract">
|
||||
<field name="name">Contract</field>
|
||||
<field name="sequence_type" ref="sequence_type_contract"/>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="create_contract_view_form">
|
||||
<field name="model">optical_equipment_create.contract</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">create_contract_form</field>
|
||||
</record>
|
||||
<record model="ir.action.wizard" id="maintenance_create_contract">
|
||||
<field name="name">Create Contract</field>
|
||||
<field name="wiz_name">optical_equipment.maintenance.contract</field>
|
||||
<field name="model">optical_equipment_maintenance.service</field>
|
||||
</record>
|
||||
<record model="ir.action.keyword" id="maintenance_create_contract_keyword">
|
||||
<field name="keyword">form_action</field>
|
||||
<field name="model">optical_equipment_maintenance.service,-1</field>
|
||||
<field name="action" ref="maintenance_create_contract"/>
|
||||
</record>
|
||||
<record model="ir.action.report" id="report_contract">
|
||||
<field name="name">Contract</field>
|
||||
<field name="model">optical_equipment.contract</field>
|
||||
<field name="report_name">optical_equipment.contract</field>
|
||||
<field name="report">optical_equipment/report/Contract.fodt</field>
|
||||
<field name="single" eval="True"/>
|
||||
</record>
|
||||
<record model="ir.action.keyword" id="report_contract_keyword">
|
||||
<field name="keyword">form_print</field>
|
||||
<field name="model">optical_equipment.contract,-1</field>
|
||||
<field name="action" ref="report_contract"/>
|
||||
</record>
|
||||
<record model="ir.action.report" id="report_prorrogation">
|
||||
<field name="name">Prorrogation</field>
|
||||
<field name="model">optical_equipment.contract</field>
|
||||
<field name="report_name">optical_equipment.contract</field>
|
||||
<field name="report">optical_equipment/report/Prorrogation.fodt</field>
|
||||
<field name="single" eval="True"/>
|
||||
</record>
|
||||
<record model="ir.action.keyword" id="report_prorrogation_keyword">
|
||||
<field name="keyword">form_print</field>
|
||||
<field name="model">optical_equipment.contract,-1</field>
|
||||
<field name="action" ref="report_prorrogation"/>
|
||||
</record>
|
||||
<menuitem
|
||||
parent="menu_equipment"
|
||||
name="Contracts Management"
|
||||
sequence="50"
|
||||
id="menu_contracts"/>
|
||||
<menuitem
|
||||
parent="menu_contracts"
|
||||
action="act_contract_form"
|
||||
sequence="30"
|
||||
id="menu_contract_form"/>
|
||||
<record model="ir.cron" id="cron_fe_delivery">
|
||||
<field name="method">optical_equipment.contract|contract_expiration</field>
|
||||
<field name="interval_number" eval="1"/>
|
||||
<field name="interval_type">hours</field>
|
||||
</record>
|
||||
</data>
|
||||
</tryton>
|
24
diary.py
Normal file
24
diary.py
Normal file
@ -0,0 +1,24 @@
|
||||
from trytond.model import (
|
||||
ModelSQL, ModelView, fields)
|
||||
|
||||
class Diary(ModelSQL, ModelView):
|
||||
'Diary'
|
||||
__name__ = 'optical_equipment_maintenance.diary'
|
||||
_rec_name = 'code'
|
||||
|
||||
code = fields.Char("Code", select=True,states={'readonly': True })
|
||||
date_expected = fields.DateTime("Expected Date", required=True)
|
||||
date_estimated = fields.DateTime("Estimated Date")
|
||||
date_end = fields.DateTime("Date End")
|
||||
maintenance_service = fields.Many2One('optical_equipment_maintenance.service', 'Maintenance Service', required=True)
|
||||
technical = fields.Many2One('company.employee', "Technical", required=True)
|
||||
state = fields.Selection([('draft', "Draft"),
|
||||
('agended', "Agended"),
|
||||
('in_progress', "In Progress"),
|
||||
('failed', "Failed"),
|
||||
('finished', "Finished")
|
||||
], "State", required=True, readonly=True, sort=True)
|
||||
|
||||
@classmethod
|
||||
def default_state(self):
|
||||
return 'draft'
|
106
diary.xml
Normal file
106
diary.xml
Normal file
@ -0,0 +1,106 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tryton>
|
||||
<data>
|
||||
<record model="res.group" id="group_agended_admin">
|
||||
<field name="name">Agended Administration</field>
|
||||
</record>
|
||||
<record model="res.user-res.group"
|
||||
id="user_admin_group_agended_admin">
|
||||
<field name="user" ref="res.user_admin"/>
|
||||
<field name="group" ref="group_agended_admin"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window" id="act_agended_list_form">
|
||||
<field name="name">Agended</field>
|
||||
<field name="res_model">optical_equipment_maintenance.diary</field>
|
||||
<field name="search_value"></field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id= "agended_list_view_tree">
|
||||
<field name="model">optical_equipment_maintenance.diary</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="name">diary_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="agended_list_view_form">
|
||||
<field name="model">optical_equipment_maintenance.diary</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">diary_form</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="act_agended_list_form_domain_draft">
|
||||
<field name="name">Draft</field>
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="domain"
|
||||
eval="[('state', '=', 'draft')]"
|
||||
pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_agended_list_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="act_agended_list_form_domain_agended">
|
||||
<field name="name">Agended</field>
|
||||
<field name="sequence" eval="20"/>
|
||||
<field name="domain"
|
||||
eval="[('state', '=', 'agended')]"
|
||||
pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_agended_list_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="act_agended_list_form_domain_in_progress">
|
||||
<field name="name">In progress</field>
|
||||
<field name="sequence" eval="30"/>
|
||||
<field name="domain"
|
||||
eval="[('state', '=', 'in_progress')]"
|
||||
pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_agended_list_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="act_agended_list_form_domain_failed">
|
||||
<field name="name">Failed</field>
|
||||
<field name="sequence" eval="30"/>
|
||||
<field name="domain"
|
||||
eval="[('state', '=', 'failed')]"
|
||||
pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_agended_list_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="act_agended_list_form_domain_finished">
|
||||
<field name="name">Finished</field>
|
||||
<field name="sequence" eval="40"/>
|
||||
<field name="domain"
|
||||
eval="[('state', '=', 'finished')]"
|
||||
pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_agended_list_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="act_agended_list_form_domain_all">
|
||||
<field name="name">All</field>
|
||||
<field name="sequence" eval="9999"/>
|
||||
<field name="domain"></field>
|
||||
<field name="act_window" ref="act_agended_list_form"/>
|
||||
</record>
|
||||
<record model="ir.sequence.type" id="sequence_type_agended">
|
||||
<field name="name">Agended</field>
|
||||
</record>
|
||||
<record model="ir.sequence.type-res.group"
|
||||
id="sequence_type_agended_group_admin">
|
||||
<field name="sequence_type" ref="sequence_type_agended"/>
|
||||
<field name="group" ref="res.group_admin"/>
|
||||
</record>
|
||||
<record model="ir.sequence.type-res.group"
|
||||
id="sequence_type_agended_group_agended_admin">
|
||||
<field name="sequence_type" ref="sequence_type_agended"/>
|
||||
<field name="group" ref="group_agended_admin"/>
|
||||
</record>
|
||||
<record model="ir.sequence" id="sequence_agended">
|
||||
<field name="name">Agended</field>
|
||||
<field name="sequence_type" ref="sequence_type_agended"/>
|
||||
</record>
|
||||
<menuitem parent="menu_equipment"
|
||||
name="Diary"
|
||||
sequence="10"
|
||||
id="menu_diary"/>
|
||||
<menuitem parent="menu_diary"
|
||||
action="act_agended_list_form"
|
||||
sequence="20"
|
||||
id="menu_agended_list_form"/>
|
||||
</data>
|
||||
</tryton>
|
@ -1,9 +1,10 @@
|
||||
###################
|
||||
Smart Vision Module
|
||||
###################
|
||||
########################
|
||||
Optical Equipment Module
|
||||
########################
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
usage
|
||||
design
|
||||
releases
|
||||
|
7
doc/releases.rst
Normal file
7
doc/releases.rst
Normal file
@ -0,0 +1,7 @@
|
||||
.. _releases-index:
|
||||
|
||||
=============
|
||||
Release notes
|
||||
=============
|
||||
|
||||
.. include:: ../CHANGELOG
|
439
equipment.py
439
equipment.py
@ -1,58 +1,405 @@
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
import datetime
|
||||
from collections import defaultdict
|
||||
from trytond.pool import Pool
|
||||
from trytond.model import ModelSQL, ModelView, fields
|
||||
from trytond.model import (
|
||||
DeactivableMixin, Workflow, ModelSQL, ModelView, Unique, fields)
|
||||
from trytond.pyson import Eval, If
|
||||
from trytond.transaction import Transaction
|
||||
from trytond.i18n import gettext
|
||||
from trytond.exceptions import UserError
|
||||
from trytond.model.exceptions import AccessError
|
||||
from trytond.wizard import (
|
||||
Button, StateAction, StateTransition, StateView, Wizard)
|
||||
from trytond.modules.company import CompanyReport
|
||||
|
||||
class OpticalEquipment(ModelSQL, ModelView):
|
||||
|
||||
_MAINTENANCE_FREQUENCY = [("none", ''),
|
||||
("6", 'Seis Meses'),
|
||||
("12", 'Doce Meses')]
|
||||
|
||||
|
||||
class OpticalEquipment(DeactivableMixin, Workflow, ModelSQL, ModelView):
|
||||
'Optical Equipment'
|
||||
__name__ = "optical_equipment.equipment"
|
||||
__name__ = 'optical_equipment.equipment'
|
||||
_rec_name = 'rec_name'
|
||||
_order_name = 'code'
|
||||
|
||||
company = fields.Many2One('company.company', "Company")
|
||||
location = fields.Many2One('stock.location', "Location")
|
||||
party = fields.Many2One('party.party', "Party")
|
||||
party_address = fields.Many2One('party.address', "Party Address")
|
||||
#origin = fields.reference("Origin", selection='get_origin', select=True)
|
||||
product = fields.Many2One('product.product', "Product")
|
||||
refurbish = fields.Boolean("Refurbish")
|
||||
equipment_type = fields.Char('type')
|
||||
risk = fields.Char('Type risk')
|
||||
use = fields.Char('Use')
|
||||
biomedical_class = fields.Char('Biomedical Class')
|
||||
main_tecnology = fields.Char('Main tecnology')
|
||||
calibration = fields.Boolean("Apply calibration")
|
||||
mark_category = fields.Many2One('product.category', 'Mark')
|
||||
model_category = fields.Many2One('product.category', "Model")
|
||||
reference = fields.Char("Reference", size=None)
|
||||
origin_country = fields.Many2One('country.country',"Origin Country")
|
||||
software_version = fields.Char("Software version", size=None)
|
||||
useful_life = fields.Char("Useful life", size=None)
|
||||
warranty = fields.Char("Warranty", size=None)
|
||||
serial = fields.Char("Serial", size=None)
|
||||
health_register = fields.Char("Health Register", size=None)
|
||||
_states={
|
||||
'readonly': Eval('state') != 'draft',
|
||||
}
|
||||
|
||||
subscription_history = fields.Many2Many('sale.subscription-optical_equipment.equipment', 'equipment', 'subscription', "Subscriptions")
|
||||
_depends = ['state']
|
||||
|
||||
_states_serial={
|
||||
'readonly': Eval('state') != 'draft',
|
||||
}
|
||||
|
||||
code = fields.Char(
|
||||
"Code", select=True,states={'readonly': True })
|
||||
|
||||
state = fields.Selection([('draft', "Draft"),
|
||||
('registred', "Registred"),
|
||||
('uncontrated', "UnContrated"),
|
||||
('contrated', "Contrated")
|
||||
], "State",
|
||||
required=True, readonly=True, sort=False)
|
||||
contract = fields.Many2One('optical_equipment.contract', "Contract", ondelete='CASCADE')
|
||||
company = fields.Many2One('company.company', "Company", readonly=True)
|
||||
location = fields.Many2One('stock.location', "Location",
|
||||
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
|
||||
)
|
||||
propietarys = fields.Many2Many('optical_equipment.equipment-party.party', 'equipment', 'party', "Propietarys")
|
||||
product = fields.Many2One('product.product', "Product",
|
||||
domain=[('equipment', '=', True)],
|
||||
states=_states,
|
||||
depends=['equipment']
|
||||
)
|
||||
refurbish = fields.Boolean("Refurbish",
|
||||
states=_states,)
|
||||
equipment_type = fields.Char('type', states={'readonly': If('product', True)})
|
||||
risk = fields.Char('Type risk',states={'readonly': If('product', True)})
|
||||
use = fields.Char('Use', states={'readonly': If('product', True)})
|
||||
biomedical_class = fields.Char('Biomedical Class', states={'readonly': If('product', True)})
|
||||
main_tecnology = fields.Char('Main tecnology', states={'readonly': If('product', True)})
|
||||
calibration = fields.Boolean("Apply calibration", states={'readonly': If('product', True)})
|
||||
mark_category = fields.Many2One('product.category', 'Mark', required=True,
|
||||
domain=[('parent', '=', None),
|
||||
('accounting', '=', False)],
|
||||
states=_states
|
||||
)
|
||||
model_category = fields.Many2One('product.category', "Model", required=True,
|
||||
domain=[('parent', '=', Eval('mark_category')),
|
||||
('accounting', '=', False)],
|
||||
states=_states,)
|
||||
reference_category = fields.Many2One('product.category', "Reference",
|
||||
domain=[('parent', '=', Eval('model_category'))],
|
||||
states=_states,
|
||||
depends=['model_category']
|
||||
)
|
||||
origin_country = fields.Many2One('country.country',"Origin Country",
|
||||
states=_states,)
|
||||
|
||||
software_version = fields.Char("Software version", size=None,
|
||||
states=_states,)
|
||||
useful_life = fields.Integer("Useful life",
|
||||
states=_states,)
|
||||
warranty = fields.Integer("Warranty",
|
||||
states=_states,)
|
||||
serial = fields.Char("Serial", size=None,
|
||||
states=_states_serial,
|
||||
depends=_depends)
|
||||
health_register = fields.Char("Health Register", size=None,
|
||||
states=_states,)
|
||||
contract_history = fields.Many2Many('optical_equipment.contract-optical_equipment.equipment', 'equipment','contract', "Contracts", states={'readonly': True})
|
||||
maintenance_history = fields.Function(
|
||||
fields.Many2Many('optical_equipment.maintenance-optical_equipment.equipment',
|
||||
'equipment', 'maintenance',"Maintenances"), 'get_maintenances_of_equipment')
|
||||
software_version = fields.Char("Software version", size=None,
|
||||
states=_states,)
|
||||
|
||||
maintenance_frequency = fields.Selection(_MAINTENANCE_FREQUENCY, "Maintenance Frequency",
|
||||
depends=['propietary'])
|
||||
purchase_origin = fields.Reference("Purchase Origin", selection='get_origin',select=True,
|
||||
states={'readonly': True})
|
||||
sale_destination = fields.Reference("Sale Destination", selection='get_destination',select=True,
|
||||
states={'readonly': True})
|
||||
shipment_destination = fields.Reference("Stock Move", selection='get_shipment', select=True,
|
||||
states={'readonly': True})
|
||||
rec_name = fields.Function(fields.Char("rec_name"), 'get_rec_name')
|
||||
|
||||
del _states_serial, _states, _depends
|
||||
|
||||
|
||||
@fields.depends('product', 'serial', 'code')
|
||||
def get_rec_name(self, name):
|
||||
name = str(self.product.name) + '@' + str(self.serial) + '/' + str(self.code)
|
||||
|
||||
return name
|
||||
|
||||
@staticmethod
|
||||
def get_origin():
|
||||
return None
|
||||
def _get_shipment():
|
||||
'Return list of Model names for shipment Reference'
|
||||
return [
|
||||
'stock.shipment.in',
|
||||
'stock.shipment.out',
|
||||
'stock.shipment.out.return',
|
||||
'stock.shipment.in.return',
|
||||
'stock.shipment.internal',
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def get_subscription_history(cls, records, names):
|
||||
pool = Pool()
|
||||
ids = []
|
||||
for record in records:
|
||||
ids.append(record.id)
|
||||
|
||||
Subscriptions = pool.get('sale.subscription-optical_equipment.equipment')
|
||||
subscriptions = Subscriptions.search([("equipment", 'in', ids)])
|
||||
subscriptions_history_id = []
|
||||
DICC = {}
|
||||
|
||||
for subscription in subscriptions:
|
||||
DICC[subscription.equipment.id] = subscription.id
|
||||
|
||||
#raise UserError(str(type(subscriptions_history_id[0])))
|
||||
#raise UserError(str(list(subscriptions_history_id[0])))
|
||||
#raise UserError(str(type(subscriptions_history_id)))
|
||||
def get_shipment(cls):
|
||||
IrModel = Pool().get('ir.model')
|
||||
get_name = IrModel.get_name
|
||||
models = cls._get_shipment()
|
||||
|
||||
return DICC
|
||||
return [(None, '')] + [(m, get_name(m)) for m in models]
|
||||
|
||||
@classmethod
|
||||
def _get_origin(cls):
|
||||
'Return list of Model names for origin Reference'
|
||||
pool = Pool()
|
||||
Purchase = pool.get('purchase.line')
|
||||
|
||||
return [Purchase.__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_destination(cls):
|
||||
'Return list of Model names for origin Reference'
|
||||
pool = Pool()
|
||||
Sale = pool.get('sale.line')
|
||||
|
||||
return [Sale.__name__]
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_destination(cls):
|
||||
Model = Pool().get('ir.model')
|
||||
get_name = Model.get_name
|
||||
models = cls._get_destination()
|
||||
|
||||
return [(None, '')] + [(m, get_name(m)) for m in models]
|
||||
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(OpticalEquipment, cls).__setup__()
|
||||
cls._transitions = ({
|
||||
('draft', 'registred'),
|
||||
('registred', 'draft'),
|
||||
('registred', 'uncontrated'),
|
||||
('uncontrated', 'contrated'),
|
||||
})
|
||||
cls._buttons.update({
|
||||
'draft': {
|
||||
'invisible': Eval('state') != 'registred'},
|
||||
'registred': {
|
||||
'invisible': Eval('state').in_(['registred', 'uncontrated', 'contrated'])}}
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def set_code(cls, equipments):
|
||||
pool = Pool()
|
||||
Config = pool.get('optical_equipment.configuration')
|
||||
config = Config(1)
|
||||
|
||||
for equipment in equipments:
|
||||
if config.equipment_sequence != None:
|
||||
if not equipment.code:
|
||||
try:
|
||||
equipment.code = config.equipment_sequence.get()
|
||||
cls.save(equipments)
|
||||
except UserError:
|
||||
raise UserError(str('Validation Error'))
|
||||
else:
|
||||
raise UserError(gettext('optical_equipment.msg_not_sequence_equipment'))
|
||||
|
||||
def get_maintenances_of_equipment(self, records):
|
||||
pool = Pool()
|
||||
MaintenancesEquipment = pool.get('optical_equipment.maintenance')
|
||||
maintenancesEquipment = set()
|
||||
|
||||
maintenancesEquipment = MaintenancesEquipment.search(['equipment', '=', self.id])
|
||||
maintenances = []
|
||||
|
||||
for key in maintenancesEquipment:
|
||||
maintenances.append(key.id)
|
||||
|
||||
return maintenances
|
||||
|
||||
@classmethod
|
||||
def default_state(cls):
|
||||
return 'draft'
|
||||
|
||||
@staticmethod
|
||||
def default_company():
|
||||
return Transaction().context.get('company')
|
||||
|
||||
@fields.depends('propietary', 'maintenance_frequency')
|
||||
def on_change_propietary(self):
|
||||
if self.propietary:
|
||||
if self.propietary.customer_type == 'ips':
|
||||
self.maintenance_frequency = "6"
|
||||
else:
|
||||
self.maintenance_frequency = "12"
|
||||
else:
|
||||
self.maintenance_frequency = "none"
|
||||
|
||||
@fields.depends('product', 'equipment_type','use',
|
||||
'biomedical_class', 'calibration',
|
||||
'mark_category', 'model_category')
|
||||
def on_change_product(self):
|
||||
if self.product:
|
||||
self.equipment_type=self.product.equipment_type
|
||||
self.use=self.product.use
|
||||
self.biomedical_class=self.product.biomedical_class
|
||||
self.calibration=self.product.calibration
|
||||
self.mark_category=self.product.mark_category
|
||||
self.model_category=self.product.model_category
|
||||
self.reference_category=self.product.reference_category
|
||||
self.useful_life=self.product.useful_life if self.product.useful_life else int(0)
|
||||
self.calibration=True if self.product.calibration else False
|
||||
self.warranty=self.product.warranty if self.product.warranty else int(0)
|
||||
self.risk=self.product.risk
|
||||
self.origin_country=self.product.origin_country
|
||||
self.use=self.product.use
|
||||
self.biomedical_class=self.product.biomedical_class
|
||||
else:
|
||||
self.equipment_type=None
|
||||
self.use=None
|
||||
self.biomedical_class=None
|
||||
self.calibration=None
|
||||
self.mark_category=None
|
||||
self.model_category=None
|
||||
self.reference_category=None
|
||||
self.useful_life=None
|
||||
self.calibration=False
|
||||
self.warranty=None
|
||||
self.risk=None
|
||||
self.origin_country=None
|
||||
self.use=None
|
||||
self.biomedical_class=None
|
||||
self.refurbish=None
|
||||
self.serial=None
|
||||
self.health_register=None
|
||||
self.software_version=None
|
||||
|
||||
@classmethod
|
||||
def delete(cls, equipments):
|
||||
for equipment in equipments:
|
||||
if equipment.purchase_origin:
|
||||
raise AccessError(
|
||||
gettext('estos equipos no se pueden borrar'))
|
||||
elif equipment.state != 'draft' and equipment.serial != None:
|
||||
raise AccessError(
|
||||
gettext('estos equipos no se pueden borrar'))
|
||||
super(OpticalEquipment, cls).delete(equipments)
|
||||
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
@Workflow.transition('draft')
|
||||
def draft(cls, equipments):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
@Workflow.transition('registred')
|
||||
def registred(cls, equipments):
|
||||
for i in equipments:
|
||||
if i.serial == None:
|
||||
raise UserError(str("El Equipo no cuenta con un Serial"))
|
||||
else:
|
||||
cls.set_code(equipments)
|
||||
|
||||
|
||||
class EquipmentMaintenance(ModelSQL, ModelView):
|
||||
'Optical Equipment - Equipment - Maintenance'
|
||||
__name__ ='optical_equipment.maintenance-optical_equipment.equipment'
|
||||
|
||||
equipment = fields.Many2One('optical_equipment.equipment', 'Equipment', select=True)
|
||||
maintenance = fields.Many2One('optical_equipment.maintenance', 'Maintenances', select=True)
|
||||
|
||||
|
||||
class EquipmentContract(ModelSQL, ModelView):
|
||||
'Optical Equipment - Contracs Equipment'
|
||||
__name__ = 'optical_equipment.contract-optical_equipment.equipment'
|
||||
|
||||
equipment = fields.Many2One('optical_equipment.equipment', 'Equipment', select=True)
|
||||
contract = fields.Many2One('optical_equipment.contract', 'Contract', select=True)
|
||||
|
||||
class EquipmentParty(ModelSQL, ModelView):
|
||||
'Optical Equipment - Party'
|
||||
__name__ = 'optical_equipment.equipment-party.party'
|
||||
|
||||
equipment = fields.Many2One('optical_equipment.equipment', "Equipment", select=True)
|
||||
party = fields.Many2One('party.party', "Party", select=True)
|
||||
|
||||
|
||||
class ChangePropietary(ModelView):
|
||||
'Change of Propietary Equipment'
|
||||
__name__ = 'optical_equipment.change_propietary.form'
|
||||
|
||||
old_propietary = fields.Many2One('party.party', 'Old Propietary',
|
||||
states={'required': True})
|
||||
equipments = fields.Many2Many('optical_equipment.equipment', None, None, "Equipments",
|
||||
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 NewPropietary(Wizard):
|
||||
'Change Propietary'
|
||||
__name__ = 'optical_equipment.change_propietary'
|
||||
|
||||
start = StateView('optical_equipment.change_propietary.form',
|
||||
'optical_equipment.change_propietary_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
|
||||
equipments = self.start.equipments
|
||||
new_propietary = self.start.new_propietary
|
||||
new_address = self.start.new_address
|
||||
|
||||
for equipment in equipments:
|
||||
equipment.propietarys += (equipment.propietary,)
|
||||
equipment.propietary = new_propietary
|
||||
equipment.propietary_address = new_address
|
||||
equipment.maintenance_frequency = "6" if new_propietary.customer_type == 'ips' else "12"
|
||||
equipment.save()
|
||||
|
||||
|
||||
class ChangeEquipment(ModelSQL):
|
||||
'Change Equipment'
|
||||
__name__ = 'optical_equipment.equipment-change_propietary.form'
|
||||
|
||||
maintenance_service = fields.Many2One('optical_equipment_maintenance.service', "Maintenance Service")
|
||||
equipment = fields.Many2One('optical_equipment.equipment', 'Equipment')
|
||||
change = fields.Many2One('optical_equipment.change_propietary.form', 'Change')
|
||||
|
||||
|
||||
class EquipmentReport(CompanyReport):
|
||||
__name__ = 'optical_equipment.equipment'
|
||||
|
||||
@classmethod
|
||||
def execute(cls, ids, data):
|
||||
with Transaction().set_context(address_with_party=True):
|
||||
return super(EquipmentReport, 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
|
||||
|
155
equipment.xml
155
equipment.xml
@ -3,34 +3,169 @@
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tryton>
|
||||
<data>
|
||||
<menuitem
|
||||
<record model="res.group" id="group_equipment_admin">
|
||||
<field name="name">Equipment Administration</field>
|
||||
</record>
|
||||
<record model="res.user-res.group"
|
||||
id="user_admin_group_equipment_admin">
|
||||
<field name="user" ref="res.user_admin"/>
|
||||
<field name="group" ref="group_equipment_admin"/>
|
||||
</record>
|
||||
<menuitem
|
||||
name="Equipment"
|
||||
sequence="40"
|
||||
id="menu_equipment"/>
|
||||
<record model="ir.action.act_window" id="act_optical_equipment">
|
||||
<record model="ir.action.act_window" id="act_optical_equipment_form">
|
||||
<field name="name">Equipments</field>
|
||||
<field name="res_model">optical_equipment.equipment</field>
|
||||
<field name="search_value"></field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="optical_equipment_view_tree">
|
||||
<record model="ir.ui.view" id="optical_equipment_view_tree">
|
||||
<field name="model">optical_equipment.equipment</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="name">optical_equipment_tree</field>
|
||||
<field name="name">equipment_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="optical_equipment_view_form">
|
||||
<field name="model">optical_equipment.equipment</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">optical_equipment_form</field>
|
||||
<field name="name">equipment_form</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_optical_equipment_view1">
|
||||
<field name="sequence" eval="50"/>
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view" ref="optical_equipment_view_tree"/>
|
||||
<field name="act_window" ref="act_optical_equipment"/>
|
||||
<field name="act_window" ref="act_optical_equipment_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_optical_equipment_view2">
|
||||
<field name="sequence" eval="50"/>
|
||||
<field name="sequence" eval="20"/>
|
||||
<field name="view" ref="optical_equipment_view_form"/>
|
||||
<field name="act_window" ref="act_optical_equipment"/>
|
||||
<field name="act_window" ref="act_optical_equipment_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="act_optical_equipment_form_domain_draft">
|
||||
<field name="name">Draft</field>
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="domain"
|
||||
eval="[('state', '=', 'draft')]"
|
||||
pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_optical_equipment_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="act_optical_equipment_form_domain_registred">
|
||||
<field name="name">Registred</field>
|
||||
<field name="sequence" eval="20"/>
|
||||
<field name="domain"
|
||||
eval="[('state', '=', 'registred')]"
|
||||
pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_optical_equipment_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="act_optical_equipment_form_domain_uncontrated">
|
||||
<field name="name">UnContrated</field>
|
||||
<field name="sequence" eval="30"/>
|
||||
<field name="domain"
|
||||
eval="[('state', '=', 'uncontrated')]"
|
||||
pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_optical_equipment_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="act_optical_equipment_form_domain_contrated">
|
||||
<field name="name">Contrated</field>
|
||||
<field name="sequence" eval="30"/>
|
||||
<field name="domain"
|
||||
eval="[('state', '=', 'contrated')]"
|
||||
pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_optical_equipment_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="act_optical_equipment_form_domain_all">
|
||||
<field name="name">All</field>
|
||||
<field name="sequence" eval="9999"/>
|
||||
<field name="domain"></field>
|
||||
<field name="act_window" ref="act_optical_equipment_form"/>
|
||||
</record>
|
||||
<record model="ir.model.button" id="draft_equipment_button">
|
||||
<field name="name">draft</field>
|
||||
<field name="string">Draft</field>
|
||||
<field name="model" search="[('model', '=', 'optical_equipment.equipment')]"/>
|
||||
</record>
|
||||
<record model="ir.model.button" id="registred_equipment_button">
|
||||
<field name="name">registred</field>
|
||||
<field name="string">Registred</field>
|
||||
<field name="confirm">Are you sure you want to registred these equipments?</field>
|
||||
<field name="model" search="[('model', '=', 'optical_equipment.equipment')]"/>
|
||||
</record>
|
||||
<menuitem parent="menu_equipment"
|
||||
action="act_optical_equipment_form"
|
||||
sequence="60"
|
||||
id="menu_optical_equipment_form"/>
|
||||
|
||||
<record model="ir.action.act_window" id="act_optical_equipment_form1">
|
||||
<field name="name">Serials</field>
|
||||
<field name="res_model">optical_equipment.equipment</field>
|
||||
<field name="search_value"></field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="optical_equipment_view_tree1">
|
||||
<field name="model">optical_equipment.equipment</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="name">equipment_serial_tree</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_optical_equipment_view3">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view" ref="optical_equipment_view_tree1"/>
|
||||
<field name="act_window" ref="act_optical_equipment_form1"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="act_optical_equipment_serial_form_domain_draft">
|
||||
<field name="name">Draft</field>
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="domain"
|
||||
eval="[('state', '=', 'draft')]"
|
||||
pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_optical_equipment_form1"/>
|
||||
</record>
|
||||
<menuitem
|
||||
parent="menu_equipment"
|
||||
action="act_optical_equipment_form1"
|
||||
sequence="70"
|
||||
id="menu_optical_equipment_serial_form"/>
|
||||
|
||||
<record model="ir.action.report" id="report_equipment">
|
||||
<field name="name">Equipment</field>
|
||||
<field name="model">optical_equipment.equipment</field>
|
||||
<field name="report_name">optical_equipment.equipment</field>
|
||||
<field name="report">optical_equipment/report/CV_Equipment.fodt</field>
|
||||
<field name="single" eval="True"/>
|
||||
</record>
|
||||
<record model="ir.action.keyword" id="report_equipment_keyword">
|
||||
<field name="keyword">form_print</field>
|
||||
<field name="model">optical_equipment.equipment,-1</field>
|
||||
<field name="action" ref="report_equipment"/>
|
||||
</record>
|
||||
<record model="ir.action.report" id="report_history_maintenance">
|
||||
<field name="name">Maintenance History</field>
|
||||
<field name="model">optical_equipment.equipment</field>
|
||||
<field name="report_name">optical_equipment.equipment</field>
|
||||
<field name="report">optical_equipment/report/Maintenance_History.fodt</field>
|
||||
<field name="single" eval="True"/>
|
||||
</record>
|
||||
<record model="ir.action.keyword" id="report_history_maintenance_keyword">
|
||||
<field name="keyword">form_print</field>
|
||||
<field name="model">optical_equipment.equipment,-1</field>
|
||||
<field name="action" ref="report_history_maintenance"/>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="change_propietary_view_form">
|
||||
<field name="model">optical_equipment.change_propietary.form</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">change_propietary_form</field>
|
||||
</record>
|
||||
<record model="ir.action.wizard" id="equipment_change_propietary">
|
||||
<field name="name">Change Propietary</field>
|
||||
<field name="wiz_name">optical_equipment.change_propietary</field>
|
||||
<field name="model">optical_equipment.equipment</field>
|
||||
</record>
|
||||
<record model="ir.action.keyword" id="equipment_change_propietary_keyword">
|
||||
<field name="keyword">form_action</field>
|
||||
<field name="model">optical_equipment.equipment,-1</field>
|
||||
<field name="action" ref="equipment_change_propietary"/>
|
||||
</record>
|
||||
<menuitem parent="menu_equipment" sequence="40" action="act_optical_equipment" id="menu_optical_equipment"/>
|
||||
</data>
|
||||
</tryton>
|
||||
|
202
icons/LICENSE
Normal file
202
icons/LICENSE
Normal file
@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
1537
locale/es.po
Normal file
1537
locale/es.po
Normal file
File diff suppressed because it is too large
Load Diff
881
maintenance.py
881
maintenance.py
@ -0,0 +1,881 @@
|
||||
# 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, 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([('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') == 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') == 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 != 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', select=True,
|
||||
domain=[('state', 'in', ['draft','in_progress', 'finished']),
|
||||
('propietary', '=', Eval('propietary'))],
|
||||
states=_states)
|
||||
code = fields.Char(
|
||||
"Code", select=True,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']),
|
||||
('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') == 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') == None, True),
|
||||
'readonly': Eval('state') == 'finished'},)
|
||||
graph_calibration = fields.Binary('Graphs')
|
||||
rec_name = fields.Function(fields.Char('rec_name'), 'get_rec_name')
|
||||
|
||||
# @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(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', select=True)
|
||||
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')
|
||||
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
|
281
maintenance.xml
Normal file
281
maintenance.xml
Normal file
@ -0,0 +1,281 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tryton>
|
||||
<data>
|
||||
<record model="ir.action.act_window" id="act_maintenance_service_form">
|
||||
<field name="name">Services Maintenance</field>
|
||||
<field name="res_model">optical_equipment_maintenance.service</field>
|
||||
<field name="search_value"></field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="maintenance_service_view_tree">
|
||||
<field name="model">optical_equipment_maintenance.service</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="name">maintenance_service_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="maintenance_service_view_form">
|
||||
<field name="model">optical_equipment_maintenance.service</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">maintenance_service_form</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_maintenance_service_view1">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view" ref="maintenance_service_view_tree"/>
|
||||
<field name="act_window" ref="act_maintenance_service_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_maintenance_service_view2">
|
||||
<field name="sequence" eval="20"/>
|
||||
<field name="view" ref="maintenance_service_view_form"/>
|
||||
<field name="act_window" ref="act_maintenance_service_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="act_maintenance_service_form_domain_draft">
|
||||
<field name="name">Draft</field>
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="domain"
|
||||
eval="[('state', '=', 'draft')]"
|
||||
pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_maintenance_service_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="act_maintenance_service_form_domain_agended">
|
||||
<field name="name">Agended</field>
|
||||
<field name="sequence" eval="20"/>
|
||||
<field name="domain"
|
||||
eval="[('state', '=', 'agended')]"
|
||||
pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_maintenance_service_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="act_maintenance_service_form_domain_in_progress">
|
||||
<field name="name">In progress</field>
|
||||
<field name="sequence" eval="30"/>
|
||||
<field name="domain"
|
||||
eval="[('state', '=', 'in_progress')]"
|
||||
pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_maintenance_service_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="act_maintenance_service_form_domain_failed">
|
||||
<field name="name">Failed</field>
|
||||
<field name="sequence" eval="30"/>
|
||||
<field name="domain"
|
||||
eval="[('state', '=', 'failed')]"
|
||||
pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_maintenance_service_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="act_maintenance_service_form_domain_finished">
|
||||
<field name="name">Finished</field>
|
||||
<field name="sequence" eval="40"/>
|
||||
<field name="domain"
|
||||
eval="[('state', '=', 'finished')]"
|
||||
pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_maintenance_service_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="act_maintenance_service_form_domain_all">
|
||||
<field name="name">All</field>
|
||||
<field name="sequence" eval="9999"/>
|
||||
<field name="domain"></field>
|
||||
<field name="act_window" ref="act_maintenance_service_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window" id="act_maintenance_form">
|
||||
<field name="name">Maintenance Lines</field>
|
||||
<field name="res_model">optical_equipment.maintenance</field>
|
||||
<field name="search_value"></field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id= "maintenance_view_tree">
|
||||
<field name="model">optical_equipment.maintenance</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="name">maintenance_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="maintenance_view_form">
|
||||
<field name="model">optical_equipment.maintenance</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">maintenance_form</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_maintenance_view1">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view" ref="maintenance_view_tree"/>
|
||||
<field name="act_window" ref="act_maintenance_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_maintenance_view2">
|
||||
<field name="sequence" eval="20"/>
|
||||
<field name="view" ref="maintenance_view_form"/>
|
||||
<field name="act_window" ref="act_maintenance_form"/>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="change_propietary_maintenance_view_form">
|
||||
<field name="model">optical_equipment.change_propietary_maintenance.form</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">change_propietary_maintenance_form</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id= "maintenance_equipment_view_form">
|
||||
<field name="model">optical_equipment.maintenance-optical_equipment.equipment</field>
|
||||
<field name="inherit" ref="maintenance_view_form"/>
|
||||
<field name="name">maintenance_equipment_form</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="maintenance_activity_view_form">
|
||||
<field name="model">optical_equipment_maintenance.activity</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">maintenance_activity_form</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="maintenance_activity_view_tree">
|
||||
<field name="model">optical_equipment_maintenance.activity</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority" eval="10"/>
|
||||
<field name="name">maintenance_activity_tree</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="act_maintenance_form_domain_draft">
|
||||
<field name="name">Draft</field>
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="domain"
|
||||
eval="[('state', '=', 'draft')]"
|
||||
pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_maintenance_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="act_maintenance_form_domain_finished">
|
||||
<field name="name">Finished</field>
|
||||
<field name="sequence" eval="40"/>
|
||||
<field name="domain"
|
||||
eval="[('state', '=', 'finished')]"
|
||||
pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="act_maintenance_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="act_maintenance_form_domain_all">
|
||||
<field name="name">All</field>
|
||||
<field name="sequence" eval="9999"/>
|
||||
<field name="domain"></field>
|
||||
<field name="act_window" ref="act_maintenance_form"/>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="maintenance_line_view_form">
|
||||
<field name="model">optical_equipment.maintenance.line</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">maintenance_line_form</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="maintenance_line_view_tree">
|
||||
<field name="model">optical_equipment.maintenance.line</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="name">maintenance_line_tree</field>
|
||||
</record>
|
||||
<record model="ir.model.button" id="assing_agended_button">
|
||||
<field name="name">assing_agended</field>
|
||||
<field name="string">Assing Agended</field>
|
||||
<field name="model" search="[('model', '=', 'optical_equipment_maintenance.service')]"/>
|
||||
</record>
|
||||
<record model="ir.model.button" id="reassing_agended_button">
|
||||
<field name="name">reassing_agended</field>
|
||||
<field name="string">Reassing Agended</field>
|
||||
<field name="model" search="[('model', '=', 'optical_equipment_maintenance.service')]"/>
|
||||
</record>
|
||||
<record model="ir.model.button" id="maintenance_service_draft_button">
|
||||
<field name="name">draft</field>
|
||||
<field name="string">Draft</field>
|
||||
<field name="model" search="[('model', '=', 'optical_equipment_maintenance.service')]"/>
|
||||
</record>
|
||||
<record model="ir.model.button" id="maintenance_service_in_progress_button">
|
||||
<field name="name">in_progress</field>
|
||||
<field name="string">In progress</field>
|
||||
<field name="model" search="[('model', '=', 'optical_equipment_maintenance.service')]"/>
|
||||
</record>
|
||||
<record model="ir.model.button" id="maintenance_service_finished_button">
|
||||
<field name="name">finished</field>
|
||||
<field name="string">Finished</field>
|
||||
<field name="model" search="[('model', '=', 'optical_equipment_maintenance.service')]"/>
|
||||
</record>
|
||||
<record model="ir.model.button" id="maintenance_finished_button">
|
||||
<field name="name">finished</field>
|
||||
<field name="string">Finished</field>
|
||||
<field name="model" search="[('model', '=', 'optical_equipment.maintenance')]"/>
|
||||
</record>
|
||||
<record model="ir.model.button" id="maintenance_samples_button">
|
||||
<field name="name">samples</field>
|
||||
<field name="string">Generate Samples</field>
|
||||
<field name="model" search="[('model', '=', 'optical_equipment.maintenance')]"/>
|
||||
</record>
|
||||
<record model="ir.model.button" id="maintenance_calibrate_button">
|
||||
<field name="name">calibrate</field>
|
||||
<field name="string">Calibrate</field>
|
||||
<field name="model" search="[('model', '=', 'optical_equipment.maintenance')]"/>
|
||||
</record>
|
||||
<record model="ir.action.report" id="report_service">
|
||||
<field name="name">Service</field>
|
||||
<field name="model">optical_equipment_maintenance.service</field>
|
||||
<field name="report_name">optical_equipment_maintenance.service</field>
|
||||
<field name="report">optical_equipment/report/Service.fodt</field>
|
||||
<field name="single" eval="True"/>
|
||||
</record>
|
||||
<record model="ir.action.keyword" id="report_service_keyword">
|
||||
<field name="keyword">form_print</field>
|
||||
<field name="model">optical_equipment_maintenance.service,-1</field>
|
||||
<field name="action" ref="report_service"/>
|
||||
</record>
|
||||
<record model="ir.action.report" id="report_cvs">
|
||||
<field name="name">Hojas de Vida</field>
|
||||
<field name="model">optical_equipment_maintenance.service</field>
|
||||
<field name="report_name">optical_equipment_maintenance.service</field>
|
||||
<field name="report">optical_equipment/report/CVS_Equipments.fodt</field>
|
||||
<field name="single" eval="True"/>
|
||||
</record>
|
||||
<record model="ir.action.keyword" id="report_cvs_keyword">
|
||||
<field name="keyword">form_print</field>
|
||||
<field name="model">optical_equipment_maintenance.service,-1</field>
|
||||
<field name="action" ref="report_cvs"/>
|
||||
</record>
|
||||
<record model="ir.action.report" id="report_maintenance_service">
|
||||
<field name="name">Maintenance Service</field>
|
||||
<field name="model">optical_equipment.maintenance</field>
|
||||
<field name="report_name">optical_equipment.maintenance</field>
|
||||
<field name="report">optical_equipment/report/Maintenance_Service.fodt</field>
|
||||
<field name="single" eval="True"/>
|
||||
</record>
|
||||
<record model="ir.action.keyword" id="report_maintenance_service_keyword">
|
||||
<field name="keyword">form_print</field>
|
||||
<field name="model">optical_equipment.maintenance,-1</field>
|
||||
<field name="action" ref="report_maintenance_service"/>
|
||||
</record>
|
||||
<record model="ir.action.report" id="report_maintenance_timeline">
|
||||
<field name="name">Time Line Maintenance Service</field>
|
||||
<field name="model">optical_equipment_maintenance.service</field>
|
||||
<field name="report_name">optical_equipment_maintenance.service</field>
|
||||
<field name="report">optical_equipment/report/Maintenance_Timeline.fodt</field>
|
||||
<field name="single" eval="True"/>
|
||||
</record>
|
||||
<record model="ir.action.keyword" id="report_maintenance_timeline_keyword">
|
||||
<field name="keyword">form_print</field>
|
||||
<field name="model">optical_equipment_maintenance.service,-1</field>
|
||||
<field name="action" ref="report_maintenance_timeline"/>
|
||||
</record>
|
||||
<record model="ir.action.report" id="report_historys_maintenances">
|
||||
<field name="name">Maintenances Historys</field>
|
||||
<field name="model">optical_equipment_maintenance.service</field>
|
||||
<field name="report_name">optical_equipment_maintenance.service</field>
|
||||
<field name="report">optical_equipment/report/Maintenances_Historys.fodt</field>
|
||||
<field name="single" eval="True"/>
|
||||
</record>
|
||||
<record model="ir.action.keyword" id="report_historys_maintenances_keyword">
|
||||
<field name="keyword">form_print</field>
|
||||
<field name="model">optical_equipment_maintenance.service,-1</field>
|
||||
<field name="action" ref="report_historys_maintenances"/>
|
||||
</record>
|
||||
<record model="ir.action.wizard" id="equipment_change_propietary_maintenance">
|
||||
<field name="name">Change Propietary Maintenance</field>
|
||||
<field name="wiz_name">optical_equipment.change_propietary_maintenance</field>
|
||||
<field name="model">optical_equipment_maintenance.service</field>
|
||||
</record>
|
||||
<record model="ir.action.keyword" id="equipment_change_propietary_maintenance_keyword">
|
||||
<field name="keyword">form_action</field>
|
||||
<field name="model">optical_equipment_maintenance.service,-1</field>
|
||||
<field name="action" ref="equipment_change_propietary_maintenance"/>
|
||||
</record>
|
||||
<menuitem parent="menu_equipment"
|
||||
action="act_maintenance_service_form"
|
||||
sequence="20"
|
||||
id="menu_maintenance_service_form"/>
|
||||
<menuitem parent="menu_maintenance_service_form"
|
||||
action="act_maintenance_form"
|
||||
sequence="30"
|
||||
id="menu_maintenance_form"/>
|
||||
</data>
|
||||
</tryton>
|
@ -1,21 +0,0 @@
|
||||
# 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 fields
|
||||
from trytond.pool import PoolMeta
|
||||
|
||||
class Measurements(metaclass=PoolMeta):
|
||||
__name__ = 'product.template'
|
||||
|
||||
temperature = fields.Float("Temperature")
|
||||
temperature_uom = fields.Many2One('product.uom', "Temperature UOM")
|
||||
frequency = fields.Float("Frequency")
|
||||
frequency_uom = fields.Many2One('product.uom', "Frequency UOM")
|
||||
wet = fields.Float("Wet")
|
||||
wet_uom = fields.Many2One('product.uom', "Wet UOM")
|
||||
voltageAC = fields.Float("Voltage AC")
|
||||
voltageAC_uom = fields.Many2One('product.uom', "Voltage AC UOM")
|
||||
voltageDC = fields.Float("Voltage DC")
|
||||
voltageDC_uom = fields.Many2One('product.uom', "Voltage DC UOM")
|
||||
|
||||
|
||||
|
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--This file file is part of Tryton. The COPYRIGHT file at the top level of this repository contains the full copyright notices and license terms. -->
|
||||
<tryton>
|
||||
<record model="ir.ui.view" id="template_view_form">
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit" ref="product.template_view_form"/>
|
||||
<field name="name">template_form</field>
|
||||
</record>
|
||||
</tryton>
|
304
move.py
Normal file
304
move.py
Normal file
@ -0,0 +1,304 @@
|
||||
from trytond.model import fields, ModelSQL, ModelView, Workflow, dualmethod
|
||||
from trytond.modules.company import CompanyReport
|
||||
from trytond.modules.company.model import employee_field, set_employee
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
from trytond.pyson import Eval, If
|
||||
from trytond.exceptions import UserError
|
||||
from itertools import groupby
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
|
||||
class Move(metaclass=PoolMeta):
|
||||
"Stock Move"
|
||||
__name__ = "stock.move"
|
||||
|
||||
|
||||
return_equipment = fields.Boolean("Devolución", states={'invisible': If(~Eval('product_equipment'), True),
|
||||
'readonly': (Eval('state').in_(['cancelled', 'done'])),}
|
||||
)
|
||||
equipment = fields.Many2One('optical_equipment.equipment', "Equipment",
|
||||
domain=[If(Eval('return_equipment', True),
|
||||
('state', 'in', ['uncontrated','contrated']),
|
||||
('state', '=', 'registred')),
|
||||
('product','=', Eval('product'))
|
||||
],
|
||||
states={'invisible': If(~Eval('product_equipment'), True),
|
||||
'readonly': (Eval('state').in_(['cancelled', 'done'])),},
|
||||
depends=['product_equipment', 'move_type'])
|
||||
equipment_serial = fields.Function(fields.Char('Serial',
|
||||
states={'readonly': True,
|
||||
'invisible': If(~Eval('product_equipment'), True)},
|
||||
depends=['product_equipment']),
|
||||
'get_equipment_serial')
|
||||
product_equipment = fields.Function(fields.Boolean("It Equipment"),'get_product_equipment')
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(Move, cls).__setup__()
|
||||
cls.origin.states['required']=True
|
||||
|
||||
@fields.depends('product')
|
||||
def get_product_equipment(self, product):
|
||||
if self.product.equipment:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
@fields.depends('equipment')
|
||||
def get_equipment_serial(self, equipment):
|
||||
if self.equipment:
|
||||
return self.equipment.serial
|
||||
else:
|
||||
return None
|
||||
|
||||
@fields.depends('product', 'equipment', 'uom')
|
||||
def on_change_product(self):
|
||||
if self.product:
|
||||
if (not self.uom
|
||||
or self.uom.category != self.product.default_uom.category):
|
||||
self.uom = self.product.default_uom
|
||||
|
||||
@fields.depends(methods=['get_equipment_serial'])
|
||||
def on_change_equipment(self):
|
||||
if self.equipment:
|
||||
self.product = self.equipment.product.id
|
||||
self.equipment_serial = self.get_equipment_serial(self.equipment)
|
||||
else:
|
||||
self.equipment_serial = None
|
||||
|
||||
|
||||
class ShipmentOut(metaclass=PoolMeta):
|
||||
"Customer Shipment"
|
||||
__name__ = 'stock.shipment.out'
|
||||
|
||||
service_maintenance_initial = fields.Boolean('Maintenance Initial', states={'readonly': True})
|
||||
sale_type = fields.Char('Type sale origin')
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(ShipmentOut, cls).__setup__()
|
||||
cls._buttons.update({
|
||||
'maintenance_initial': {
|
||||
'invisible': ((Eval('service_maintenance_initial',True))
|
||||
| (Eval('sale_type').in_(['maintenance', 'replaces'])))}
|
||||
})
|
||||
|
||||
@classmethod
|
||||
def view_attributes(cls):
|
||||
return super(ShipmentOut, cls).view_attributes() + [
|
||||
('//page[@name="inventory_moves"]', 'states', {
|
||||
'invisible': False,
|
||||
}),]
|
||||
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
@Workflow.transition('done')
|
||||
@set_employee('done_by')
|
||||
def done(cls, shipments):
|
||||
pool = Pool()
|
||||
Move = pool.get('stock.move')
|
||||
Date = pool.get('ir.date')
|
||||
Locations = pool.get('stock.location')
|
||||
Equipments = pool.get('optical_equipment.equipment')
|
||||
for shipment in shipments:
|
||||
for move in shipment.inventory_moves:
|
||||
count = 0
|
||||
if move.equipment:
|
||||
equipment = move.equipment
|
||||
Id = equipment.id
|
||||
equipment = Equipments.search(['id', '=',Id])[0]
|
||||
equipment.propietary = shipment.customer.id
|
||||
equipment.propietary_address= shipment.delivery_address.id
|
||||
equipment.location = Locations.search(['name', '=', 'Cliente'])[0].id
|
||||
equipment.state="uncontrated"
|
||||
equipment.shipment_destination = shipment
|
||||
equipment.sale_destination = shipment.outgoing_moves[count].origin
|
||||
equipment.propietarys += (shipment.customer,)
|
||||
equipment.maintenance_frequency = "6" if shipment.customer.customer_type == "ips" else "12"
|
||||
count+=1
|
||||
equipment.save()
|
||||
else:
|
||||
count+=1
|
||||
|
||||
Move.delete([
|
||||
m for s in shipments for m in s.outgoing_moves
|
||||
if m.state == 'staging'])
|
||||
|
||||
Move.do([m for s in shipments for m in s.outgoing_moves])
|
||||
for company, c_shipments in groupby(
|
||||
shipments, key=lambda s: s.company):
|
||||
with Transaction().set_context(company=company.id):
|
||||
today = Date.today()
|
||||
cls.write([s for s in c_shipments if not s.effective_date], {
|
||||
'effective_date': today,
|
||||
})
|
||||
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
def maintenance_initial(cls, shipments):
|
||||
pool = Pool()
|
||||
MaintenanceService = pool.get('optical_equipment_maintenance.service')
|
||||
Maintenance = pool.get('optical_equipment.maintenance')
|
||||
SaleLine = pool.get('sale.line')
|
||||
|
||||
Equipments = pool.get('optical_equipment.equipment')
|
||||
|
||||
for shipment in shipments:
|
||||
serial = False
|
||||
number_equipments = 0
|
||||
maintenance_required = 0
|
||||
for move in shipment.inventory_moves:
|
||||
if move.product_equipment and move.equipment:
|
||||
serial = True
|
||||
number_equipments +=1
|
||||
if move.equipment.product.maintenance_required:
|
||||
maintenance_required +=1
|
||||
elif not move.product_equipment:
|
||||
serial = True
|
||||
else:
|
||||
serial = False
|
||||
|
||||
if number_equipments < 1 or maintenance_required < 1:
|
||||
raise UserError(str("No se generó un mantenimiento inicial dado que los equipos no requiren mantenimiento, ó no se encontró ningún producto de tipo equipo en este envío."))
|
||||
break
|
||||
|
||||
sale_origin = shipment.outgoing_moves[0].origin.sale
|
||||
maintenanceService = MaintenanceService.search(['sale_origin', '=', sale_origin])
|
||||
if maintenanceService == []:
|
||||
maintenanceService = MaintenanceService(
|
||||
sale_date=shipment.outgoing_moves[0].origin.sale.sale_date,
|
||||
sale_origin=shipment.outgoing_moves[0].origin.sale,
|
||||
maintenance_type='initial',
|
||||
propietary=shipment.customer.id,
|
||||
propietary_address=shipment.delivery_address.id,
|
||||
state='draft')
|
||||
maintenanceService.save()
|
||||
else:
|
||||
maintenanceService = maintenanceService[0]
|
||||
maintenanceService.state = 'draft'
|
||||
maintenanceService.save()
|
||||
|
||||
if serial == True:
|
||||
for move in shipment.inventory_moves:
|
||||
if move.product_equipment and move.equipment and move.equipment.product.template.maintenance_required:
|
||||
maintenance = Maintenance(
|
||||
service_maintenance=maintenanceService.id,
|
||||
maintenance_type='initial',
|
||||
propietary=shipment.customer.id,
|
||||
equipment_calibrate= True if move.equipment.product.calibration else False,
|
||||
propietary_address=shipment.delivery_address.id,
|
||||
equipment=move.equipment.id,
|
||||
initial_operation = move.equipment.product.initial_operation,
|
||||
check_equipment = move.equipment.product.template.check_equipment,
|
||||
check_electric_system = move.equipment.product.template.check_electric_system,
|
||||
clean_int_ext = move.equipment.product.template.clean_int_ext,
|
||||
clean_eyes = move.equipment.product.template.clean_eyes,
|
||||
check_calibration = move.equipment.product.template.check_calibration,
|
||||
temperature_min = maintenanceService.temperature_min,
|
||||
temperature_max = maintenanceService.temperature_max,
|
||||
temperature_uom = maintenanceService.temperature_uom.id,
|
||||
moisture_min = maintenanceService.moisture_min,
|
||||
moisture_max = maintenanceService.moisture_max,
|
||||
moisture_uom = maintenanceService.moisture_uom.id)
|
||||
maintenance.save()
|
||||
shipment.service_maintenance_initial = True
|
||||
shipment.save()
|
||||
else:
|
||||
raise UserError(str('Por favor Primero debe Asignar un serial a todos los Equipos.'))
|
||||
|
||||
|
||||
class ShipmentInternal(metaclass=PoolMeta):
|
||||
'Shipment Interncal'
|
||||
__name__ = 'stock.shipment.internal'
|
||||
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
@Workflow.transition('done')
|
||||
@set_employee('done_by')
|
||||
def done(cls, shipments):
|
||||
pool = Pool()
|
||||
Move = pool.get('stock.move')
|
||||
Date = pool.get('ir.date')
|
||||
|
||||
for shipment in shipments:
|
||||
for move in shipment.moves:
|
||||
if move.equipment:
|
||||
move.equipment.location = shipment.to_location
|
||||
move.equipment.save()
|
||||
|
||||
Move.do([m for s in shipments for m in s.incoming_moves])
|
||||
cls.write([s for s in shipments if not s.effective_date], {
|
||||
'effective_date': Date.today(),})
|
||||
|
||||
|
||||
class ShipmentOutReturn(metaclass=PoolMeta):
|
||||
"Customer Shipment Return"
|
||||
__name__ = 'stock.shipment.out.return'
|
||||
|
||||
service_maintenance_initial = fields.Boolean('Maintenance Initial', states={'readonly': True})
|
||||
sale_type = fields.Char('Type sale origin')
|
||||
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
@Workflow.transition('received')
|
||||
@set_employee('received_by')
|
||||
def receive(cls, shipments):
|
||||
Move = Pool().get('stock.move')
|
||||
Equipments = Pool().get('optical_equipment.equipment')
|
||||
Locations = Pool().get('stock.location')
|
||||
Move.do([m for s in shipments for m in s.incoming_moves])
|
||||
for s in shipments:
|
||||
for m in s.incoming_moves:
|
||||
if m.equipment:
|
||||
equipment = m.equipment
|
||||
Id = equipment.id
|
||||
equipment = Equipments.search(['id', '=',Id])[0]
|
||||
equipment.propietary = s.company.party.id
|
||||
equipment.propietary_address= s.company.party.addresses[0].id
|
||||
equipment.location = m.to_location.id
|
||||
equipment.state="registred"
|
||||
equipment.save()
|
||||
|
||||
cls.create_inventory_moves(shipments)
|
||||
# Set received state to allow done transition
|
||||
cls.write(shipments, {'state': 'received'})
|
||||
to_do = [s for s in shipments
|
||||
if s.warehouse_storage == s.warehouse_input]
|
||||
|
||||
|
||||
if to_do:
|
||||
cls.done(to_do)
|
||||
class PickingListDeliveryReport(CompanyReport):
|
||||
__name__ = 'stock.shipment.out.picking_list1'
|
||||
|
||||
@classmethod
|
||||
def execute(cls, ids, data):
|
||||
with Transaction().set_context(address_with_party=True):
|
||||
return super(PickingListDeliveryReport, 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
|
||||
|
||||
|
||||
class CapacitationReport(CompanyReport):
|
||||
__name__ = 'stock.shipment.out.capacitation_note'
|
||||
|
||||
@classmethod
|
||||
def execute(cls, ids, data):
|
||||
with Transaction().set_context(address_with_party=True):
|
||||
return super(CapacitationReport, 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
|
42
move.xml
Normal file
42
move.xml
Normal file
@ -0,0 +1,42 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--This file file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tryton>
|
||||
<record model="ir.ui.view" id="move_view_list_shipment">
|
||||
<field name="model">stock.move</field>
|
||||
<field name="inherit" ref="stock.move_view_list_shipment"/>
|
||||
<field name="name">move_list_shipment</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="move_view_form">
|
||||
<field name="model">stock.move</field>
|
||||
<field name="inherit" ref="stock.move_view_form"/>
|
||||
<field name="name">move_form</field>
|
||||
</record>
|
||||
<record model="ir.model.button" id="maintenance_initial_button">
|
||||
<field name="name">maintenance_initial</field>
|
||||
<field name="string">Maintenance Initial</field>
|
||||
<field name="model" search="[('model', '=', 'stock.shipment.out')]"/>
|
||||
</record>
|
||||
<record model="ir.action.report" id="report_shipment_out_picking_list1">
|
||||
<field name="name">Acta Entrega</field>
|
||||
<field name="model">stock.shipment.out</field>
|
||||
<field name="report_name">stock.shipment.out.picking_list1</field>
|
||||
<field name="report">optical_equipment/report/Delivery_Certificated.fodt</field>
|
||||
</record>
|
||||
<record model="ir.action.keyword" id="report_shipment_out_picking_list1_keyword">
|
||||
<field name="keyword">form_print</field>
|
||||
<field name="model">stock.shipment.out,-1</field>
|
||||
<field name="action" ref="report_shipment_out_picking_list1"/>
|
||||
</record>
|
||||
<record model="ir.action.report" id="report_capacitation">
|
||||
<field name="name">Capacitation</field>
|
||||
<field name="model">stock.shipment.out</field>
|
||||
<field name="report_name">stock.shipment.out.picking_list1</field>
|
||||
<field name="report">optical_equipment/report/Capacitation.fodt</field>
|
||||
</record>
|
||||
<record model="ir.action.keyword" id="report_capacitation_keyword">
|
||||
<field name="keyword">form_print</field>
|
||||
<field name="model">stock.shipment.out,-1</field>
|
||||
<field name="action" ref="report_capacitation"/>
|
||||
</record>
|
||||
</tryton>
|
22
party.py
22
party.py
@ -1,11 +1,25 @@
|
||||
# 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.pool import PoolMeta
|
||||
from trytond.model import ModelSQL, ModelView, fields
|
||||
from . import equipment
|
||||
from trytond.pyson import Eval, If
|
||||
|
||||
_CLIENT_TYPE = [('ips', 'IPS'),
|
||||
('optica', 'Optica')]
|
||||
#from . import equipment
|
||||
|
||||
_CUSTOMER_TYPE = [('ips', 'IPS'),
|
||||
('optica', 'Optica'),
|
||||
('otro', 'Otro')]
|
||||
|
||||
class Party(metaclass=PoolMeta):
|
||||
__name__ = 'party.party'
|
||||
|
||||
client_type = fields.Selection(_CLIENT_TYPE, 'Client type')
|
||||
customer_type = fields.Selection(_CUSTOMER_TYPE, "Customer Type")
|
||||
|
||||
|
||||
class Address(metaclass=PoolMeta):
|
||||
__name__ = 'party.address'
|
||||
|
||||
campus = fields.Boolean("Campus")
|
||||
party_related = fields.Many2One('party.party', "Party Related",
|
||||
states ={ 'invisible': (~Eval("campus"))})
|
||||
|
21
party.xml
21
party.xml
@ -2,14 +2,25 @@
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tryton>
|
||||
<record model="ir.ui.view" id="party_view_form">
|
||||
<field name="model">party.party</field>
|
||||
<field name="inherit" ref="party.party_view_form"/>
|
||||
<field name="name">party_form</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="party_view_tree">
|
||||
<field name="model">party.party</field>
|
||||
<field name="inherit" ref="party.party_view_tree"/>
|
||||
<field name="name">party_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="party_view_form">
|
||||
<field name="model">party.party</field>
|
||||
<field name="inherit" ref="party.party_view_form"/>
|
||||
<field name="name">party_form</field>
|
||||
</record>
|
||||
<!-- Party Address -->
|
||||
<record model="ir.ui.view" id="address_view_tree">
|
||||
<field name="model">party.address</field>
|
||||
<field name="inherit" ref="party.address_view_tree"/>
|
||||
<field name="name">address_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="address_view_form">
|
||||
<field name="model">party.address</field>
|
||||
<field name="inherit" ref="party.address_view_form"/>
|
||||
<field name="name">address_form</field>
|
||||
</record>
|
||||
</tryton>
|
||||
|
433
product.py
433
product.py
@ -1,108 +1,397 @@
|
||||
#This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
#txhis repository contains the full copyright notices and license terms
|
||||
from sql import Literal
|
||||
from sql.operators import Equal
|
||||
|
||||
#this repository contains the full copyright notices and license terms
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
from trytond.model import (
|
||||
ModelView, ModelSQL, fields, Exclude)
|
||||
from trytond.pyson import If, Eval
|
||||
from trytond.pyson import Bool, If, Eval, Id
|
||||
|
||||
|
||||
|
||||
|
||||
_RISK = [('uno', 'I'),
|
||||
_RISK = [('n/a', "No aplíca"),
|
||||
('uno', 'I'),
|
||||
('dosA', 'IIA'),
|
||||
('dosB', 'IIB')]
|
||||
|
||||
_USE = [('medico', 'Médico'),
|
||||
_USE = [('', ""),
|
||||
('medico', 'Médico'),
|
||||
('basico', 'Basico'),
|
||||
('apoyo', 'Apoyo')]
|
||||
|
||||
_BIOMEDICAL_CLASS = [('diagnostico', 'Diagnóstico'),
|
||||
('rehabilitación', 'Rehabilitación')]
|
||||
_BIOMEDICAL_CLASS = [
|
||||
('n/a', "No aplíca"),
|
||||
('diagnostico', 'Diagnóstico'),
|
||||
('rehabilitación', 'Rehabilitación')]
|
||||
|
||||
_MAIN_TECNOLOGY = [('mecanico', 'Mecánico'),
|
||||
('electrico', 'Electrico'),
|
||||
('electronico', 'Electrónico'),
|
||||
('hidraulico', 'Hidraulico'),
|
||||
('neumatico', 'Neumatico')]
|
||||
_MAIN_TECNOLOGY = [
|
||||
('', ""),
|
||||
('mecanico', 'Mecánico'),
|
||||
('electrico', 'Electrico'),
|
||||
('electronico', 'Electrónico'),
|
||||
('hidraulico', 'Hidraulico'),
|
||||
('neumatico', 'Neumatico')]
|
||||
|
||||
_EQUIPMENT_TYPE = [('mobiliario_optico', 'Mobiliario óptico'),
|
||||
('refraccion', 'Refracción'),
|
||||
('medico', 'Medicion'),
|
||||
('accesorios', 'Accesorios')]
|
||||
_EQUIPMENT_TYPE = [
|
||||
('', ""),
|
||||
('mobiliario_optico', 'Mobiliario óptico'),
|
||||
('refraccion', 'Refracción'),
|
||||
('medico', 'Medicion'),
|
||||
('accesorios', 'Accesorios')]
|
||||
|
||||
NON_MEASURABLE = ['service']
|
||||
|
||||
class Template(metaclass=PoolMeta):
|
||||
'Template'
|
||||
__name__ = 'product.template'
|
||||
|
||||
product = fields.Many2One('optical_equipment.maintenance', "Maintenance Activity",
|
||||
ondelete='CASCADE', select=True)
|
||||
equipment = fields.Boolean('It is equipment',
|
||||
states={'invisible': Eval('type', 'goods') != 'goods',
|
||||
})
|
||||
maintenance_activity = fields.Boolean('Maintenance Activity',
|
||||
states={'invisible': Eval('type', 'service') != 'service',
|
||||
'readonly': If(Eval('equipment',True), True)
|
||||
| If(Eval('replacement',True), True)
|
||||
})
|
||||
replacement = fields.Boolean('Replacement',
|
||||
states={'invisible': Eval('type', 'goods') != 'goods',
|
||||
'readonly': If(Eval('equipment',True), True)
|
||||
| If(Eval('maintenance_activity',True), True)
|
||||
})
|
||||
|
||||
equipment = fields.Boolean('It is equipment')
|
||||
equipment_type = fields.Selection(_EQUIPMENT_TYPE, 'Equipment type')
|
||||
maintenance_required = fields.Boolean('Miantenance Required',
|
||||
states={'invisible': (Eval('type', 'goods') != 'goods')})
|
||||
equipment_type = fields.Selection(_EQUIPMENT_TYPE, 'Equipment type',
|
||||
states={'required': Eval('equipment', False)})
|
||||
risk = fields.Selection(_RISK, 'Type risk')
|
||||
use = fields.Selection(_USE, 'Use')
|
||||
biomedical_class = fields.Selection(_BIOMEDICAL_CLASS,
|
||||
'Biomedical Class')
|
||||
main_tecnology = fields.Selection(_MAIN_TECNOLOGY,
|
||||
'Main tecnology')
|
||||
use = fields.Selection(_USE, 'Use',
|
||||
states={'required': Eval('equipment', False)},
|
||||
depends={'equipment'})
|
||||
biomedical_class = fields.Selection(_BIOMEDICAL_CLASS,'Biomedical Class',
|
||||
states={'required': Eval('equipment', False)})
|
||||
main_tecnology = fields.Selection(_MAIN_TECNOLOGY,'Main tecnology',
|
||||
states={'required': Eval('equipment', False)})
|
||||
calibration = fields.Boolean("Apply calibration")
|
||||
observation = fields.Text('Observation')
|
||||
mark_category = fields.Many2One('product.category', 'Mark')
|
||||
model_category = fields.Many2One('product.category', "Model")
|
||||
reference = fields.Char("Reference", size=None)
|
||||
|
||||
# Mark, Category, Reference
|
||||
mark_category = fields.Many2One('product.category', 'Mark',
|
||||
domain=[('parent', '=', None),
|
||||
('accounting', '=', False)],
|
||||
states={'required': Eval('equipment', False)})
|
||||
model_category = fields.Many2One('product.category', "Model",
|
||||
domain=[('parent', '=', Eval('mark_category')),
|
||||
('accounting', '=', False)],
|
||||
states={'required': Eval('equipment', False)})
|
||||
reference_category = fields.Many2One('product.category', "Reference",
|
||||
domain=[('parent', '=', Eval('model_category'))],)
|
||||
|
||||
# Iformation Equipment
|
||||
origin_country = fields.Many2One('country.country',"Origin Country")
|
||||
software_version = fields.Char(
|
||||
"Software version", size=None)
|
||||
useful_life = fields.Char(
|
||||
"Useful life", size=None)
|
||||
warranty = fields.Char(
|
||||
"Warranty", size=None)
|
||||
serial = fields.Char(
|
||||
"Serial", size=None)
|
||||
health_register = fields.Char(
|
||||
"Health_Register", size=None)
|
||||
refurbish = fields.Boolean('Refurbish')
|
||||
software_required = fields.Boolean("Software Required")
|
||||
software_version = fields.Char("Software version",
|
||||
states={'invisible': If(~Eval('software_required'), True)},
|
||||
depends={'software_required'})
|
||||
|
||||
@staticmethod
|
||||
def default_equipment():
|
||||
return False
|
||||
#These are measurements required for the equipments, are in this place
|
||||
# for manage of class 'product.template'
|
||||
|
||||
@staticmethod
|
||||
def default_risk():
|
||||
return None
|
||||
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)})
|
||||
frequency = fields.Float("Frequency")
|
||||
frequency_uom = fields.Many2One('product.uom', "Frequency UOM",
|
||||
domain=[('category', '=', Id('optical_equipment', 'uom_cat_frequency'))],
|
||||
states={'invisible' : If(Eval('frequency') == None, True)}
|
||||
)
|
||||
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)},
|
||||
)
|
||||
electrical_equipment = fields.Boolean("Electrical Equipment")
|
||||
frequency = fields.Float("Frequency",
|
||||
states={'invisible': ~Bool(Eval('electrical_equipment'))})
|
||||
frequency_uom = fields.Many2One('product.uom', "Frequency UOM",
|
||||
domain=[('category', '=', Id('optical_equipment', 'uom_cat_frequency'))],
|
||||
states={'invisible' : If(Eval('frequency') == None, True) |
|
||||
~Eval('electrical_equipment', True)},
|
||||
)
|
||||
voltageAC = fields.Float("Voltage AC",
|
||||
states={'invisible': ~Bool(Eval('electrical_equipment'))})
|
||||
voltageAC_uom = fields.Many2One('product.uom', "Voltage AC UOM",
|
||||
domain=[('category', '=', Id('optical_equipment', 'uom_cat_electrical_tension'))],
|
||||
states={'invisible' : If(Eval('voltageAC') == None, True) |
|
||||
~Eval('electrical_equipment', True)},
|
||||
)
|
||||
voltageDC = fields.Float("Voltage DC",
|
||||
states={'invisible': ~Bool(Eval('electrical_equipment'))})
|
||||
voltageDC_uom = fields.Many2One('product.uom', "Voltage DC UOM",
|
||||
domain=[('category', '=', Id('optical_equipment', 'uom_cat_electrical_tension'))],
|
||||
states={'invisible' : If(Eval('voltageDC') == None, True) |
|
||||
~Eval('electrical_equipment', True)},)
|
||||
|
||||
useful_life = fields.Integer("Useful life")
|
||||
warranty = fields.Integer("Warranty")
|
||||
|
||||
@staticmethod
|
||||
def default_use():
|
||||
return None
|
||||
#### calibration parameters
|
||||
use_pattern = fields.Many2One('optical_equipment.use_pattern', "Use Pattern", ondelete='RESTRICT',
|
||||
states={'required': Eval('calibration', True)})
|
||||
measuring_range = fields.Selection([
|
||||
('dioptria', "Dioptria"),
|
||||
('mmhg', "mmHg")], "Rango de Medición")
|
||||
MEP = fields.Float("MEP", states={'required': Eval('calibration', False)},)
|
||||
uncertainy_pattern = fields.Float("Uncertainy Pattern", states={'required': Eval('calibration', True)},
|
||||
help="Agregar valores separados por ',' Ej:-5,+5,-10,+10")
|
||||
k_pattern = fields.Char("K Pattern",states={'required': Eval('calibration', False)},
|
||||
help="Agregar valores separados por ',' Ej:-5,+5,-10,+10")
|
||||
k_pattern_list = fields.One2Many('optical_equipment.product_pattern', 'product', "List of patterns K",
|
||||
states={'required': Eval('calibration', False)},)
|
||||
resolution_type = fields.Selection([('',""),
|
||||
('analoga', "Analoga"),
|
||||
('digital', "Digital")], "Resolution Type",
|
||||
states={'required': Eval('calibration', False)},)
|
||||
d_resolution = fields.Float("Resolution d",
|
||||
states={'invisible': If(Eval('resolution_type') != 'digital', True)},)
|
||||
analog_resolution = fields.Float("Analog resolution",
|
||||
states={'invisible': If(Eval('resolution_type') != 'analoga', True),},)
|
||||
a_factor_resolution = fields.Float("(a) Resolution",
|
||||
states={'invisible': If(Eval('resolution_type') != 'analoga', True)},)
|
||||
Usubi = fields.Integer("Usub i",states={'required': Eval('calibration', False)},)
|
||||
|
||||
@staticmethod
|
||||
def default_biomedical_class():
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def default_main_tecnology():
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def default_calibration():
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def default_refurbish():
|
||||
return False
|
||||
|
||||
@fields.depends('mark_category', 'model_category')
|
||||
def on_change_mark_category(self):
|
||||
if self.mark_category:
|
||||
self.model_category = None
|
||||
|
||||
#maintenance activities
|
||||
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")
|
||||
optical = fields.Boolean("Optical")
|
||||
check_calibration = fields.Boolean("Verificar Calibración")
|
||||
|
||||
@classmethod
|
||||
def view_attributes(cls):
|
||||
return super(Template, cls).view_attributes() + [
|
||||
('//page[@id="features"]', 'states', {
|
||||
'invisible': ~Eval('equipment'),
|
||||
})]
|
||||
'invisible': ~Eval('equipment'),}),
|
||||
('//page[@id="calibration"]', 'states', {
|
||||
'invisible': ~Eval('calibration')},),
|
||||
('//page[@id="maintenance_activities"]', 'states', {
|
||||
'invisible': ~Eval('maintenance_required')},)
|
||||
|
||||
]
|
||||
|
||||
@classmethod
|
||||
@fields.depends('measuring_range')
|
||||
def default_measuring_range(self):
|
||||
return 'dioptria'
|
||||
|
||||
@classmethod
|
||||
@fields.depends('temperature_min')
|
||||
def default_temperature_min(self):
|
||||
return 0
|
||||
|
||||
@classmethod
|
||||
@fields.depends('temperature_max')
|
||||
def default_temperature_max(self):
|
||||
return 0
|
||||
|
||||
@classmethod
|
||||
def default_frequency(cls):
|
||||
return 0
|
||||
|
||||
@classmethod
|
||||
def default_moisture_min(cls):
|
||||
return 0
|
||||
|
||||
@classmethod
|
||||
def default_moisture_max(cls):
|
||||
return 0
|
||||
|
||||
@classmethod
|
||||
def default_voltageDC(cls):
|
||||
return 0
|
||||
|
||||
@classmethod
|
||||
def default_voltageAC(cls):
|
||||
return 0
|
||||
|
||||
def default_risk():
|
||||
return 'n/a'
|
||||
|
||||
def default_use():
|
||||
return None
|
||||
|
||||
def default_biomedical_class():
|
||||
return 'n/a'
|
||||
|
||||
|
||||
def default_main_tecnology():
|
||||
return None
|
||||
|
||||
|
||||
def default_calibration():
|
||||
return False
|
||||
|
||||
|
||||
def default_refurbish():
|
||||
return False
|
||||
|
||||
|
||||
def default_refurbish():
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
@fields.depends('temperature')
|
||||
def default_temperature_uom(self):
|
||||
pool = Pool()
|
||||
Measurements = pool.get('product.uom')
|
||||
measurement = Measurements.search(['name', '=', 'Celsius'])[0].id
|
||||
|
||||
return measurement
|
||||
|
||||
@classmethod
|
||||
def default_frequency_uom(cls):
|
||||
pool = Pool()
|
||||
Measurements = pool.get('product.uom')
|
||||
measurement = Measurements.search(['name', '=', 'Hertz'])[0].id
|
||||
|
||||
return measurement
|
||||
|
||||
@classmethod
|
||||
def default_moisture_uom(cls):
|
||||
pool = Pool()
|
||||
Measurements = pool.get('product.uom')
|
||||
measurement = Measurements.search(['name', '=', 'Relative Humedity'])[0].id
|
||||
|
||||
return measurement
|
||||
|
||||
@classmethod
|
||||
def default_voltageAC_uom(cls):
|
||||
pool = Pool()
|
||||
Measurements = pool.get('product.uom')
|
||||
measurement = Measurements.search(['name', '=', 'Volt'])[0].id
|
||||
|
||||
return measurement
|
||||
|
||||
@classmethod
|
||||
def default_voltageDC_uom(cls):
|
||||
pool = Pool()
|
||||
Measurements = pool.get('product.uom')
|
||||
measurement = Measurements.search(['name', '=', 'Volt'])[0].id
|
||||
|
||||
return measurement
|
||||
|
||||
@fields.depends('voltageDC', 'voltageDC_uom')
|
||||
def on_change_voltageDC_uom(self):
|
||||
pool = Pool()
|
||||
Measurements = pool.get('product.uom')
|
||||
measurement = Measurements.search(['name', '=', 'Volt'])[0].id
|
||||
self.voltageDC_uom = measurement
|
||||
|
||||
@fields.depends('software_required', 'software_version')
|
||||
def on_change_with_sotfware_required(self):
|
||||
self.software_version = None
|
||||
|
||||
@fields.depends('d_resolution', 'analog_resolution', 'a_factor_resolution')
|
||||
def on_change_resolution_type(self):
|
||||
self.d_resolution = None
|
||||
self.analog_resolution = None
|
||||
self.a_factor_resolution = None
|
||||
|
||||
@fields.depends('equipment', 'replacement')
|
||||
def on_change_equipment(self):
|
||||
if self.equipment:
|
||||
self.replacement=False
|
||||
self.maintenance_activity=False
|
||||
self.calibration=False
|
||||
self.mark_category = None
|
||||
self.model_category = None
|
||||
self.reference_category = None
|
||||
self.equipment_type = None
|
||||
self.risk = 'n/a'
|
||||
self.biomedical_class = 'n/a'
|
||||
self.use = ''
|
||||
self.useful_life = 0
|
||||
self.warranty = 0
|
||||
|
||||
@fields.depends('mark_category', 'model_category', 'reference_category')
|
||||
def on_change_mark_category(self):
|
||||
if not self.mark_category:
|
||||
self.model_category = None
|
||||
self.reference_category = None
|
||||
|
||||
@fields.depends('model_category', 'reference_category')
|
||||
def on_change_model_category(self):
|
||||
if not self.model_category:
|
||||
self.reference_category = None
|
||||
|
||||
@fields.depends('electrical_equipment')
|
||||
def on_change_electrical_equipment(self):
|
||||
if self.electrical_equipment:
|
||||
self.voltageAC = 0
|
||||
self.voltageDC = 0
|
||||
self.frequency = 0
|
||||
|
||||
@classmethod
|
||||
def copy(cls, templates, default=None):
|
||||
if default is None:
|
||||
default = {}
|
||||
else:
|
||||
default = default.copy()
|
||||
default.setdefault('code', None)
|
||||
default.setdefault('images', None)
|
||||
return super().copy(templates, default=default)
|
||||
|
||||
|
||||
class Product(metaclass=PoolMeta):
|
||||
__name__ = 'product.product'
|
||||
|
||||
@classmethod
|
||||
def copy(cls, products, default=None):
|
||||
if default is None:
|
||||
default = {}
|
||||
else:
|
||||
default = default.copy()
|
||||
|
||||
default.setdefault('suffix_code', None)
|
||||
default.setdefault('code', None)
|
||||
default.setdefault('poduct', None)
|
||||
default.setdefault('images', None)
|
||||
return super().copy(products, default=default)
|
||||
|
||||
|
||||
class Image(metaclass=PoolMeta):
|
||||
__name__ = 'product.image'
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super().__setup__()
|
||||
|
||||
@classmethod
|
||||
def copy(cls, images, default=None):
|
||||
if default is None:
|
||||
default = {}
|
||||
else:
|
||||
default = default.copy()
|
||||
default.setdefault('template', None)
|
||||
default.setdefault('product', None)
|
||||
return super().copy(images, default=default)
|
||||
|
||||
|
||||
class UsePattern(ModelSQL,ModelView):
|
||||
"Use Pattern"
|
||||
__name__ = 'optical_equipment.use_pattern'
|
||||
_rec_name = 'name_pattern'
|
||||
|
||||
name_pattern = fields.Char('Name Pattern', required=True)
|
||||
|
||||
class Pattern(ModelSQL, ModelView):
|
||||
"Pattern K of equipment"
|
||||
__name__ = 'optical_equipment.product_pattern'
|
||||
_rec_name = 'pattern'
|
||||
|
||||
product = fields.Many2One('product.template', "Template", ondelete='CASCADE')
|
||||
pattern = fields.Float("Value Pattern")
|
||||
|
61
product.xml
61
product.xml
@ -3,6 +3,43 @@
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tryton>
|
||||
<data>
|
||||
<record model="ir.action.act_window" id="act_use_pattern">
|
||||
<field name="name">Use Pattern</field>
|
||||
<field name="res_model">optical_equipment.use_pattern</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="use_pattern_view_tree">
|
||||
<field name="model">optical_equipment.use_pattern</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="name">use_pattern_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="use_pattern_view_form">
|
||||
<field name="model">optical_equipment.use_pattern</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">use_pattern_form</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_use_pattern_view1">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view" ref="use_pattern_view_tree"/>
|
||||
<field name="act_window" ref="act_use_pattern"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_use_pattern_view2">
|
||||
<field name="sequence" eval="20"/>
|
||||
<field name="view" ref="use_pattern_view_form"/>
|
||||
<field name="act_window" ref="act_use_pattern"/>
|
||||
</record>
|
||||
<menuitem
|
||||
name="Properties of Equipments"
|
||||
parent="product.menu_configuration"
|
||||
sequence="10"
|
||||
id="menu_properties_equipments"
|
||||
icon="tryton-settings"/>
|
||||
<menuitem
|
||||
parent="menu_properties_equipments"
|
||||
name="Pattern Use"
|
||||
action="act_use_pattern"
|
||||
sequence="10"
|
||||
id="menu_pattern"
|
||||
icon="tryton-list"/>
|
||||
<record model="ir.ui.view" id="template_view_form1">
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit" ref="product.template_view_form"/>
|
||||
@ -13,5 +50,29 @@
|
||||
<field name="inherit" ref="product.template_view_tree"/>
|
||||
<field name="name">template_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="pattern_view_form">
|
||||
<field name="model">optical_equipment.product_pattern</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">pattern_form</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="pattern_view_tree">
|
||||
<field name="model">optical_equipment.product_pattern</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="name">pattern_tree</field>
|
||||
</record>
|
||||
|
||||
<!--Patterns use-->
|
||||
<record model="optical_equipment.use_pattern" id="schematic_eye">
|
||||
<field name="name_pattern">Schematic Eye</field>
|
||||
</record>
|
||||
<record model="optical_equipment.use_pattern" id="trial_lens">
|
||||
<field name="name_pattern">Trial Lens</field>
|
||||
</record>
|
||||
<record model="optical_equipment.use_pattern" id="calibration_weights">
|
||||
<field name="name_pattern">Calibration Weights</field>
|
||||
</record>
|
||||
<record model="optical_equipment.use_pattern" id="calibration_spheres">
|
||||
<field name="name_pattern">Calibration Spheres</field>
|
||||
</record>
|
||||
</data>
|
||||
</tryton>
|
||||
|
228
purchase.py
228
purchase.py
@ -1,72 +1,190 @@
|
||||
#This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
#txhis repository contains the full copyright notices and license terms
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
from trytond.model import ModelView, ModelSQL, fields
|
||||
from trytond.model import (
|
||||
ModelView, ModelSQL, Workflow, fields)
|
||||
from trytond.modules.product import price_digits, round_price
|
||||
from trytond.pyson import Eval, If, Bool
|
||||
from trytond.exceptions import UserError
|
||||
from trytond.i18n import gettext
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
|
||||
class Purchase(metaclass=PoolMeta):
|
||||
"Purchase Equipment"
|
||||
__name__ = 'purchase.purchase'
|
||||
|
||||
equipment_create = fields.Boolean("Equipments Creates", readonly=True)
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(Purchase, cls).__setup__()
|
||||
cls._buttons.update({
|
||||
'create_equipments': {
|
||||
'invisible': If(Eval('invoice_state') == 'none', True) |
|
||||
If(Bool(Eval('equipment_create')), True),
|
||||
'depends': ['invoice_state'],}})
|
||||
|
||||
@classmethod
|
||||
def copy(cls, purchases, default=None):
|
||||
if default is None:
|
||||
default = {}
|
||||
else:
|
||||
default = default.copy()
|
||||
|
||||
default.setdefault('number', None)
|
||||
default.setdefault('invoice_state', 'none')
|
||||
default.setdefault('invoices_ignored', None)
|
||||
default.setdefault('moves', None)
|
||||
default.setdefault('shipment_state', 'none')
|
||||
default.setdefault('purchase_date', None)
|
||||
default.setdefault('quoted_by')
|
||||
default.setdefault('confirmed_by')
|
||||
default.setdefault('equipment_create', None)
|
||||
|
||||
return super(Purchase, cls).copy(purchases, default=default)
|
||||
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
def process(cls, purchases):
|
||||
pool = Pool()
|
||||
Equipment = pool.get('optical_equipment.equipment')
|
||||
#raise UserError(str(type(Equipment)))
|
||||
Line = pool.get('purchase.line')
|
||||
lines = []
|
||||
process, done = [], []
|
||||
cls.lock(purchases)
|
||||
for purchase in purchases:
|
||||
"""if purchase.state not in {'confirmed', 'processing', 'done'}:
|
||||
continue
|
||||
purchase.create_invoice()
|
||||
purchase.set_invoice_state()
|
||||
purchase.create_move('in')
|
||||
return_moves = purchase.create_move('return')
|
||||
if return_moves:
|
||||
purchase.create_return_shipment(return_moves)
|
||||
purchase.set_shipment_state()
|
||||
"""
|
||||
#raise UserError(str(dir(purchase)))
|
||||
#equipment = Equipment()
|
||||
def create_equipments(cls, purchases):
|
||||
if len(purchases) == 1:
|
||||
pool = Pool()
|
||||
Equipment = pool.get('optical_equipment.equipment')
|
||||
Config = pool.get('optical_equipment.configuration')
|
||||
config = Config(1)
|
||||
|
||||
purchase = purchases[0]
|
||||
|
||||
for line in purchase.lines:
|
||||
#raise UserError(str(dir(line)))
|
||||
equipment = Equipment(
|
||||
company=line.company,
|
||||
equipment_type=line.product.equipment_type,
|
||||
party_address=line.address_equipment,
|
||||
product=line.product,
|
||||
risk=line.product.risk,
|
||||
use=line.product.use,
|
||||
biomedical_class=line.product.biomedical_class,
|
||||
calibration=line.product.calibration,
|
||||
refurbish=line.refurbish,
|
||||
serial=line.serial_equipment,
|
||||
software_version=line.product.software_version,
|
||||
)
|
||||
equipment.save()
|
||||
#raise UserError(str([equipment.serial, equipment.software_version]))
|
||||
""" line.set_actual_quantity()
|
||||
lines.append(line)
|
||||
|
||||
if purchase.is_done():
|
||||
if purchase.state != 'done':
|
||||
if purchase.state == 'confirmed':
|
||||
process.append(purchase)
|
||||
done.append(purchase)
|
||||
elif purchase.state != 'processing':
|
||||
process.append(purchase)
|
||||
Line.save(lines)
|
||||
if process:
|
||||
cls.proceed(process)
|
||||
if done:
|
||||
cls.do(done)"""
|
||||
if line.product.equipment:
|
||||
for i in range(0,int(line.quantity)):
|
||||
equipment = Equipment(
|
||||
company=line.company,
|
||||
location=line.to_location,
|
||||
equipment_type=line.product.equipment_type,
|
||||
propietary=line.company.party,
|
||||
propietary_address=line.address_equipment,
|
||||
product=line.product,
|
||||
model_category=line.product.model_category,
|
||||
mark_category=line.product.mark_category,
|
||||
reference_category=line.product.reference_category,
|
||||
useful_life=line.product.useful_life if line.product.useful_life else 0,
|
||||
calibration=True if line.product.calibration else False,
|
||||
warranty=line.product.warranty if line.product.warranty else 0,
|
||||
risk=line.product.risk,
|
||||
origin_country=line.product.origin_country,
|
||||
use=line.product.use,
|
||||
biomedical_class=line.product.biomedical_class,
|
||||
refurbish=line.refurbish,
|
||||
serial=None if line.quantity > 1 else line.serial_equipment,
|
||||
health_register=line.health_register,
|
||||
software_version=line.product.software_version if line.product.software_required else "No Aplica",
|
||||
maintenance_frequency="none",
|
||||
purchase_origin=line,
|
||||
)
|
||||
equipment.save()
|
||||
else:
|
||||
continue
|
||||
purchase.equipment_create = True
|
||||
cls.save(purchases)
|
||||
else:
|
||||
raise UserError(str("Número de Compras Invalido."))
|
||||
|
||||
|
||||
class Line(metaclass=PoolMeta):
|
||||
"Purchase Line Equipment"
|
||||
__name__ = 'purchase.line'
|
||||
|
||||
address_equipment = fields.Many2One('party.address', "Direccion")
|
||||
serial_equipment = fields.Char("Serial", size=None, required=True)
|
||||
origin_country = fields.Many2One('country.country',"Origin Country")
|
||||
address_equipment = fields.Many2One('party.address', "Direccion", required=True)
|
||||
serial_equipment = fields.Char("Serial", size=None,
|
||||
states={'invisible': If(Eval('quantity') > 1, True)})
|
||||
refurbish = fields.Boolean("Refurbish")
|
||||
product_equipment = fields.Boolean("Product Equipment",
|
||||
states={'readonly': True})
|
||||
software_version = fields.Char("Software version")
|
||||
health_register = fields.Char("Health Register", states={'required': Eval('product_equipment', True)})
|
||||
|
||||
|
||||
@classmethod
|
||||
def default_address_equipment(cls):
|
||||
pool = Pool()
|
||||
Company = pool.get('company.company')
|
||||
company = Transaction().context.get('company')
|
||||
if company:
|
||||
company = Company(company)
|
||||
|
||||
return company.party.addresses[0].id
|
||||
|
||||
@fields.depends(
|
||||
'product', 'quantity', methods=['_get_context_purchase_price'])
|
||||
def on_change_quantity(self):
|
||||
Product = Pool().get('product.product')
|
||||
if self.quantity > 1 or self.quantity < 1:
|
||||
self.serial_equipment = None
|
||||
|
||||
if not self.product:
|
||||
self.serial_equipment = None
|
||||
return
|
||||
|
||||
with Transaction().set_context(self._get_context_purchase_price()):
|
||||
self.unit_price = Product.get_purchase_price([self.product],
|
||||
abs(self.quantity or 0))[self.product.id]
|
||||
|
||||
if self.unit_price:
|
||||
self.unit_price = round_price(self.unit_price)
|
||||
|
||||
@fields.depends('product', 'unit', 'purchase', '_parent_purchase.party',
|
||||
'_parent_purchase.invoice_party', 'product_supplier', 'product_equipment',
|
||||
'serial_equipment', 'software_version', 'health_register',
|
||||
'refurbish', methods=['compute_taxes', 'compute_unit_price',
|
||||
'_get_product_supplier_pattern'])
|
||||
def on_change_product(self):
|
||||
if not self.product:
|
||||
self.product_equipment = False
|
||||
self.address_equipment = None
|
||||
self.serial_equipment = None
|
||||
self.software_version = None
|
||||
self.health_register = None
|
||||
self.refurbish = None
|
||||
self.quantity = None
|
||||
self.unit_price = None
|
||||
self.unit = None
|
||||
|
||||
return
|
||||
|
||||
party = None
|
||||
if self.purchase:
|
||||
party = self.purchase.invoice_party or self.purchase.party
|
||||
# Set taxes before unit_price to have taxes in context of purchase
|
||||
# price
|
||||
self.taxes = self.compute_taxes(party)
|
||||
|
||||
category = self.product.purchase_uom.category
|
||||
if not self.unit or self.unit.category != category:
|
||||
self.unit = self.product.purchase_uom
|
||||
|
||||
product_suppliers = list(self.product.product_suppliers_used(
|
||||
**self._get_product_supplier_pattern()))
|
||||
if len(product_suppliers) == 1:
|
||||
self.product_supplier, = product_suppliers
|
||||
elif (self.product_supplier
|
||||
and self.product_supplier not in product_suppliers):
|
||||
self.product_supplier = None
|
||||
|
||||
self.unit_price = self.compute_unit_price()
|
||||
|
||||
self.type = 'line'
|
||||
self.amount = self.on_change_with_amount()
|
||||
if self.product.equipment:
|
||||
self.product_equipment = True
|
||||
self.address_equipment = self.default_address_equipment()
|
||||
if self.product.software_required:
|
||||
self.software_version = self.product.software_version
|
||||
|
||||
@classmethod
|
||||
def view_attributes(cls):
|
||||
return super(Line, cls).view_attributes() + [
|
||||
('//page[@id="equipment"]', 'states', {
|
||||
'invisible': ~Eval('product_equipment', True),
|
||||
})]
|
||||
|
32
purchase.xml
32
purchase.xml
@ -3,10 +3,40 @@
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tryton>
|
||||
<data>
|
||||
<record model="ir.ui.view" id="purchase_line_view_form">
|
||||
<record model="ir.ui.view" id="purchase_view_form">
|
||||
<field name="model">purchase.purchase</field>
|
||||
<field name="inherit" ref="purchase.purchase_view_form"/>
|
||||
<field name="name">purchase_form</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="purchase_line_view_form">
|
||||
<field name="model">purchase.line</field>
|
||||
<field name="inherit" ref="purchase.purchase_line_view_form"/>
|
||||
<field name="name">purchase_line_form</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="product_view_list_purchase_line">
|
||||
<field name="model">product.product</field>
|
||||
<field name="inherit" ref="purchase.product_view_list_purchase_line"/>
|
||||
<field name="name">product_list_purchase_line</field>
|
||||
</record>
|
||||
<record model="ir.model.button" id="purchase_create_equipments">
|
||||
<field name="name">create_equipments</field>
|
||||
<field name="string">Create Equipments</field>
|
||||
<field name="model" search="[('model', '=', 'purchase.purchase')]"/>
|
||||
</record>
|
||||
<record model="ir.action.report" id="purchase.report_purchase">
|
||||
<field name="active" eval="False"/>
|
||||
</record>
|
||||
<record model="ir.action.report" id="report_purchase">
|
||||
<field name="name">Purchase</field>
|
||||
<field name="model">purchase.purchase</field>
|
||||
<field name="report_name">purchase.purchase</field>
|
||||
<field name="report">optical_equipment/report/Purchase.fodt</field>
|
||||
<field name="single" eval="True"/>
|
||||
</record>
|
||||
<record model="ir.action.keyword" id="report_purchase_keyword">
|
||||
<field name="keyword">form_print</field>
|
||||
<field name="model">purchase.purchase,-1</field>
|
||||
<field name="action" ref="report_purchase"/>
|
||||
</record>
|
||||
</data>
|
||||
</tryton>
|
||||
|
1813
report/CVS_Equipments.fodt
Normal file
1813
report/CVS_Equipments.fodt
Normal file
File diff suppressed because it is too large
Load Diff
1720
report/CV_Equipment.fodt
Normal file
1720
report/CV_Equipment.fodt
Normal file
File diff suppressed because it is too large
Load Diff
1979
report/Calibration.fodt
Normal file
1979
report/Calibration.fodt
Normal file
File diff suppressed because it is too large
Load Diff
2080
report/Calibrations.fodt
Normal file
2080
report/Calibrations.fodt
Normal file
File diff suppressed because it is too large
Load Diff
1170
report/Capacitation.fodt
Normal file
1170
report/Capacitation.fodt
Normal file
File diff suppressed because it is too large
Load Diff
4951
report/Contract.fodt
Normal file
4951
report/Contract.fodt
Normal file
File diff suppressed because it is too large
Load Diff
4761
report/Delivery_Certificated.fodt
Normal file
4761
report/Delivery_Certificated.fodt
Normal file
File diff suppressed because it is too large
Load Diff
1680
report/Maintenance_History.fodt
Normal file
1680
report/Maintenance_History.fodt
Normal file
File diff suppressed because it is too large
Load Diff
1561
report/Maintenance_Service.fodt
Normal file
1561
report/Maintenance_Service.fodt
Normal file
File diff suppressed because it is too large
Load Diff
1354
report/Maintenance_Timeline.fodt
Normal file
1354
report/Maintenance_Timeline.fodt
Normal file
File diff suppressed because it is too large
Load Diff
1689
report/Maintenances_Historys.fodt
Normal file
1689
report/Maintenances_Historys.fodt
Normal file
File diff suppressed because it is too large
Load Diff
1435
report/Payment.fodt
Normal file
1435
report/Payment.fodt
Normal file
File diff suppressed because it is too large
Load Diff
1596
report/Purchase.fodt
Normal file
1596
report/Purchase.fodt
Normal file
File diff suppressed because it is too large
Load Diff
5221
report/Sale.fodt
Normal file
5221
report/Sale.fodt
Normal file
File diff suppressed because it is too large
Load Diff
5698
report/Sale_Internal.fodt
Normal file
5698
report/Sale_Internal.fodt
Normal file
File diff suppressed because it is too large
Load Diff
1722
report/Service.fodt
Normal file
1722
report/Service.fodt
Normal file
File diff suppressed because it is too large
Load Diff
1202
report/balance_sale_party.fods
Normal file
1202
report/balance_sale_party.fods
Normal file
File diff suppressed because it is too large
Load Diff
378
sale.py
378
sale.py
@ -1,21 +1,379 @@
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
from trytond.model import ModelView, ModelSQL, fields
|
||||
from trytond.modules.currency.fields import Monetary
|
||||
from trytond.pyson import Eval, Bool, If, Get, Equal
|
||||
from decimal import Decimal
|
||||
from trytond.modules.product import price_digits
|
||||
from trytond.transaction import Transaction
|
||||
from trytond.model import Workflow
|
||||
from trytond.modules.company.model import (
|
||||
employee_field, set_employee, reset_employee)
|
||||
|
||||
from trytond.exceptions import UserError
|
||||
|
||||
from trytond.wizard import (
|
||||
Button, StateAction, StateTransition, StateView, Wizard)
|
||||
|
||||
|
||||
class Sale(metaclass=PoolMeta):
|
||||
'Sale'
|
||||
__name__ = 'sale.sale'
|
||||
|
||||
quote_number = fields.Char("Quote Number", readonly=True)
|
||||
sale_type = fields.Selection([('maintenance', 'Maintenance'),
|
||||
('equipments', 'Equipments'),
|
||||
('replaces', 'Replaces')], "Sale Type", required=True,
|
||||
states={'readonly': Eval('state') != 'draft'})
|
||||
maintenance_type = fields.Selection([('', ""),
|
||||
('preventive', 'Preventive'),
|
||||
('corrective', 'Corrective')
|
||||
], "Maintenance Type",
|
||||
states={
|
||||
'invisible': Eval('sale_type') != "maintenance",
|
||||
'required': Eval('sale_type') == "maintenance",
|
||||
'readonly': Eval('state') != 'draft'},
|
||||
depends=['sale_type'])
|
||||
|
||||
contract_ref = fields.Reference("Contract Base", selection='get_origin_contract',
|
||||
domain={'optical_equipment.contract': [
|
||||
('party', '=', Eval('party')),
|
||||
('state', '=', 'closed'),
|
||||
]},
|
||||
states={'invisible': (Eval('sale_type') != 'maintenance')},
|
||||
search_context={
|
||||
'related_party': Eval('party'),
|
||||
},)
|
||||
agended = fields.Boolean("Scheduling",states={
|
||||
'invisible': (Eval('sale_type') != 'maintenance'),
|
||||
'readonly': True})
|
||||
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(Sale, cls).__setup__()
|
||||
cls.contact.states['required']=True
|
||||
cls.description.states['required']=True
|
||||
cls.sale_date.states['required']=True
|
||||
cls.payment_term.states['required']=True
|
||||
cls._buttons.update({
|
||||
'draft': {
|
||||
'invisible': (Eval('state').in_(
|
||||
['cancelled', 'draft']))},
|
||||
'report': {}})
|
||||
|
||||
cls._transitions |= set((
|
||||
('draft', 'quotation'),
|
||||
('quotation', 'confirmed'),
|
||||
('confirmed', 'processing'),
|
||||
('confirmed', 'draft'),
|
||||
('processing', 'processing'),
|
||||
('processing', 'done'),
|
||||
('done', 'processing'),
|
||||
('draft', 'cancelled'),
|
||||
('quotation', 'cancelled'),
|
||||
('quotation', 'draft'),
|
||||
('cancelled', 'draft'),
|
||||
('processing', 'draft')
|
||||
))
|
||||
|
||||
@fields.depends('lines', 'sale_type', 'agended')
|
||||
def on_chage_sale_type(self):
|
||||
self.lines= []
|
||||
if self.sale_type != "maintenance":
|
||||
self.agended = False
|
||||
elif self.sale_type == "maintenance":
|
||||
self.invoice_method = 'order'
|
||||
|
||||
@classmethod
|
||||
def default_agended(self):
|
||||
return False
|
||||
|
||||
@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]
|
||||
|
||||
def _get_shipment_sale(self, Shipment, key):
|
||||
values = {
|
||||
'customer': self.shipment_party or self.party,
|
||||
'delivery_address': self.shipment_address,
|
||||
'company': self.company,
|
||||
'sale_type': self.sale_type,
|
||||
'service_maintenance_initial': True if self.sale_type != 'equipments' else False,
|
||||
}
|
||||
values.update(dict(key))
|
||||
|
||||
return Shipment(**values)
|
||||
|
||||
@classmethod
|
||||
def set_quote_number(cls, sales):
|
||||
'''
|
||||
Fill the number field with the sale sequence
|
||||
'''
|
||||
pool = Pool()
|
||||
Config = pool.get('optical_equipment.configuration')
|
||||
config = Config(1)
|
||||
for sale in sales:
|
||||
if config.equipment_sequence != None:
|
||||
if not sale.quote_number:
|
||||
try:
|
||||
sale.quote_number = config.sale_quote_number.get()
|
||||
cls.save(sales)
|
||||
except UserError:
|
||||
raise UserError(str('Validation Error'))
|
||||
else:
|
||||
raise UserError(gettext('optical_equipment.msg_not_sequence_quote'))
|
||||
|
||||
@classmethod
|
||||
def copy(cls, sales, default=None):
|
||||
if default is None:
|
||||
default = {}
|
||||
else:
|
||||
default = default.copy()
|
||||
|
||||
default.setdefault('number', None)
|
||||
default.setdefault('invoice_state', 'none')
|
||||
default.setdefault('invoices_ignored', None)
|
||||
default.setdefault('moves', None)
|
||||
default.setdefault('shipment_state', 'none')
|
||||
default.setdefault('quoted_by')
|
||||
default.setdefault('confirmed_by')
|
||||
|
||||
return super(Sale, cls).copy(sales, default=default)
|
||||
|
||||
@classmethod
|
||||
@ModelView.button_action(
|
||||
'optical_equipment.wizard_print_balance_sale_party')
|
||||
def report(cls, sales):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
@Workflow.transition('quotation')
|
||||
def quote(cls, sales):
|
||||
pool = Pool()
|
||||
AdvancePaymentCondition = pool.get('sale.advance_payment.condition')
|
||||
for sale in sales:
|
||||
sale.check_for_quotation()
|
||||
cls.set_quote_number(sales)
|
||||
|
||||
for sale in sales:
|
||||
sale.set_advance_payment_term()
|
||||
cls.save(sales)
|
||||
|
||||
@classmethod
|
||||
@ModelView.button_action(
|
||||
'optical_equipment.wizard_confirm_sale_date')
|
||||
@Workflow.transition('confirmed')
|
||||
@set_employee('confirmed_by')
|
||||
def confirm(cls, sales):
|
||||
pool = Pool()
|
||||
Configuration = pool.get('sale.configuration')
|
||||
transaction = Transaction()
|
||||
context = transaction.context
|
||||
cls.set_sale_date(sales)
|
||||
cls.store_cache(sales)
|
||||
config = Configuration(1)
|
||||
|
||||
MaintenanceService = pool.get('optical_equipment_maintenance.service')
|
||||
for sale in sales:
|
||||
if sale.sale_type == 'maintenance':
|
||||
for line in sale.lines:
|
||||
maintenanceService = MaintenanceService(
|
||||
description=sale.description,
|
||||
maintenance_type=sale.maintenance_type,
|
||||
state_agended='no_agenda',
|
||||
propietary=sale.party,
|
||||
propietary_address=sale.shipment_address,
|
||||
contract_origin=sale.contract_ref if sale.contract_ref else None,
|
||||
sale_origin=sale,
|
||||
sale_date=sale.sale_date,
|
||||
state="draft"
|
||||
)
|
||||
maintenanceService.save()
|
||||
sale.agended = True
|
||||
sale.state="confirmed"
|
||||
sale.save()
|
||||
|
||||
cls.set_number([sale])
|
||||
with Transaction().set_context(
|
||||
queue_name='sale',
|
||||
queue_scheduled_at=config.sale_process_after):
|
||||
cls.__queue__.process(sales)
|
||||
|
||||
|
||||
class SaleLine(metaclass=PoolMeta):
|
||||
'SaleLine'
|
||||
__name__ = 'sale.line'
|
||||
|
||||
address_equipment = fields.Many2One('party.address', "Direccion")
|
||||
product_equipment = fields.Boolean("Product Equipment")
|
||||
unit_digits = fields.Function(fields.Integer('Unit Digits'),
|
||||
'on_change_with_unit_digits')
|
||||
|
||||
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
def process(cls, sales):
|
||||
states = {'confirmed', 'processing', 'done'}
|
||||
sales = [s for s in sales if s.state in states]
|
||||
cls.lock(sales)
|
||||
cls._process_invoice(sales)
|
||||
cls._process_shipment(sales)
|
||||
cls._process_invoice_shipment_states(sales)
|
||||
cls._process_state(sales)
|
||||
def __setup__(cls):
|
||||
super(SaleLine, cls).__setup__()
|
||||
cls.product.domain.append(
|
||||
If(Eval('_parent_sale.sale_type') == 'maintenance',
|
||||
[('type', '=', 'service'),
|
||||
('maintenance_activity', '=', True)], []))
|
||||
cls.product.domain.append(If(Eval('_parent_sale.sale_type') == 'replaces',
|
||||
[('replacement', '=', True)], []))
|
||||
|
||||
|
||||
def on_change_with_unit_digits(self, name=None):
|
||||
if self.unit:
|
||||
return self.unit.digits
|
||||
return 2
|
||||
|
||||
|
||||
@fields.depends('product', 'unit', 'quantity', 'sale',
|
||||
'_parent_sale.party', '_parent_sale.sale_type', methods=['_get_tax_rule_pattern',
|
||||
'_get_context_sale_price','on_change_with_amount'])
|
||||
def on_change_product(self):
|
||||
Product = Pool().get('product.product')
|
||||
if not self.product:
|
||||
self.product_equipment = False
|
||||
self.unit = None
|
||||
self.quantity = None
|
||||
return
|
||||
|
||||
else:
|
||||
party = None
|
||||
|
||||
if self.sale.sale_type == 'equipments':
|
||||
self.quantity = 1
|
||||
|
||||
if self.sale and self.sale.party:
|
||||
self.product_equipment = False
|
||||
party = self.sale.party
|
||||
|
||||
# Set taxes before unit_price to have taxes in context of sale price
|
||||
taxes = []
|
||||
pattern = self._get_tax_rule_pattern()
|
||||
for tax in self.product.customer_taxes_used:
|
||||
if party and party.customer_tax_rule:
|
||||
tax_ids = party.customer_tax_rule.apply(tax, pattern)
|
||||
if tax_ids:
|
||||
taxes.extend(tax_ids)
|
||||
continue
|
||||
taxes.append(tax.id)
|
||||
|
||||
if party and party.customer_tax_rule:
|
||||
tax_ids = party.customer_tax_rule.apply(None, pattern)
|
||||
if tax_ids:
|
||||
taxes.extend(tax_ids)
|
||||
self.taxes = taxes
|
||||
|
||||
category = self.product.sale_uom.category
|
||||
if not self.unit or self.unit.category != category:
|
||||
self.unit = self.product.sale_uom
|
||||
self.unit_digits = self.product.sale_uom.digits
|
||||
|
||||
with Transaction().set_context(self._get_context_sale_price()):
|
||||
self.unit_price = Product.get_sale_price([self.product],
|
||||
self.quantity or 0)[self.product.id]
|
||||
|
||||
if self.unit_price:
|
||||
self.unit_price = self.unit_price.quantize(
|
||||
Decimal(1) / 10 ** self.__class__.unit_price.digits[1])
|
||||
|
||||
self.type = 'line'
|
||||
self.amount = self.on_change_with_amount()
|
||||
|
||||
if self.product.equipment:
|
||||
self.product_equipment = True
|
||||
|
||||
def get_move(self, shipment_type):
|
||||
'''
|
||||
Return moves for the sale line according to shipment_type
|
||||
'''
|
||||
|
||||
pool = Pool()
|
||||
Move = pool.get('stock.move')
|
||||
|
||||
if self.type != 'line':
|
||||
return
|
||||
|
||||
if not self.product:
|
||||
return
|
||||
|
||||
if self.product.type not in Move.get_product_types():
|
||||
return
|
||||
|
||||
if (shipment_type == 'out') != (self.quantity >= 0):
|
||||
return
|
||||
|
||||
|
||||
quantity = (self._get_move_quantity(shipment_type)
|
||||
- self._get_shipped_quantity(shipment_type))
|
||||
|
||||
quantity = self.unit.round(quantity)
|
||||
|
||||
if quantity <= 0:
|
||||
return
|
||||
|
||||
if not self.sale.party.customer_location:
|
||||
raise PartyLocationError(
|
||||
gettext('sale.msg_sale_customer_location_required',
|
||||
sale=self.sale.rec_name,
|
||||
party=self.sale.party.rec_name))
|
||||
|
||||
move = Move()
|
||||
move.quantity = quantity
|
||||
move.uom = self.unit
|
||||
move.product = self.product
|
||||
move.from_location = self.from_location
|
||||
move.to_location = self.to_location
|
||||
move.state = 'draft'
|
||||
move.company = self.sale.company
|
||||
|
||||
if move.on_change_with_unit_price_required():
|
||||
move.unit_price = self.unit_price
|
||||
move.currency = self.sale.currency
|
||||
|
||||
move.planned_date = self.planned_shipping_date
|
||||
move.invoice_lines = self._get_move_invoice_lines(shipment_type)
|
||||
move.origin = self
|
||||
|
||||
return move
|
||||
|
||||
class SaleDate(ModelView):
|
||||
'Confirmacíon Fecha de Venta'
|
||||
__name__ = 'optical_equipment.confirm_sale_date.form'
|
||||
|
||||
sale_date = fields.Date("Fecha Venta", required=True)
|
||||
|
||||
class ConfirmSaleDate(Wizard):
|
||||
'Confirmacíon Fecha de Venta'
|
||||
__name__ = 'optical_equipment.confirm_sale_date'
|
||||
|
||||
start = StateView('optical_equipment.confirm_sale_date.form',
|
||||
'optical_equipment.confirm_sale_date_view_form',[
|
||||
Button('Confirmar', 'confirm_date', 'tryton-ok', default=True),
|
||||
])
|
||||
|
||||
confirm_date = StateAction('sale.act_sale_form')
|
||||
|
||||
def default_start(self, fields):
|
||||
if self.record:
|
||||
return {'sale_date': self.record.sale_date}
|
||||
|
||||
def do_confirm_date(self, action):
|
||||
self.record.sale_date = self.start.sale_date
|
||||
self.record.state = 'processing'
|
||||
self.record.save()
|
||||
|
||||
|
78
sale.xml
78
sale.xml
@ -1,9 +1,77 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--This file file is part of Tryton. The COPYRIGHT file at the top level of this repository contains the full copyright notices and license terms. -->
|
||||
<!--This file file is part of Tryton. The COPYRIGHT file at the top level
|
||||
of this repository contains the full copyright notices and license terms. -->
|
||||
<tryton>
|
||||
<record model="ir.ui.view" id="sale_line_view_form">
|
||||
<field name="model">sale.line</field>
|
||||
<field name="inherit" ref="sale.sale_line_view_form"/>
|
||||
<field name="name">sale_line_form</field>
|
||||
<record model="ir.ui.view" id="sale_view_tree">
|
||||
<field name="model">sale.sale</field>
|
||||
<field name="inherit" ref="sale.sale_view_tree"/>
|
||||
<field name="name">sale_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="sale_view_form">
|
||||
<field name="model">sale.sale</field>
|
||||
<field name="inherit" ref="sale.sale_view_form"/>
|
||||
<field name="name">sale_form</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="product_view_list_sale_line">
|
||||
<field name="model">product.product</field>
|
||||
<field name="inherit" ref="sale.product_view_list_sale_line"/>
|
||||
<field name="name">product_list_sale_line</field>
|
||||
</record>
|
||||
<record model="ir.sequence" id="sequence_quote_sale">
|
||||
<field name="name">Sale Quote</field>
|
||||
<field name="sequence_type" ref="sale.sequence_type_sale"/>
|
||||
</record>
|
||||
<record model="ir.action.report" id="sale.report_sale">
|
||||
<field name="active" eval="False"/>
|
||||
</record>
|
||||
<record model="ir.model.button" id="report_balance_party_sale">
|
||||
<field name="name">report</field>
|
||||
<field name="string">Estado de Cuenta</field>
|
||||
<field name="model" search="[('model', '=', 'sale.sale')]"/>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="confirm_sale_date_view_form">
|
||||
<field name="model">optical_equipment.confirm_sale_date.form</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">confirm_sale_date_form</field>
|
||||
</record>
|
||||
<record model="ir.action.wizard" id="wizard_confirm_sale_date">
|
||||
<field name="name">Confirm Sale Date</field>
|
||||
<field name="wiz_name">optical_equipment.confirm_sale_date</field>
|
||||
</record>
|
||||
<record model="ir.action.report" id="report_sale">
|
||||
<field name="name">Sale Equipments</field>
|
||||
<field name="model">sale.sale</field>
|
||||
<field name="report_name">sale.sale</field>
|
||||
<field name="report">optical_equipment/report/Sale_Internal.fodt</field>
|
||||
<field name="single" eval="True"/>
|
||||
</record>
|
||||
<record model="ir.action.keyword" id="report_sale_keyword">
|
||||
<field name="keyword">form_print</field>
|
||||
<field name="model">sale.sale,-1</field>
|
||||
<field name="action" ref="report_sale"/>
|
||||
</record>
|
||||
<record model="ir.action.report" id="report_sale_internal">
|
||||
<field name="name">Sale Equipments Internal</field>
|
||||
<field name="model">sale.sale</field>
|
||||
<field name="report_name">sale.sale</field>
|
||||
<field name="report">optical_equipment/report/Sale.fodt</field>
|
||||
<field name="single" eval="True"/>
|
||||
</record>
|
||||
<record model="ir.action.keyword" id="report_sale_internal_keyword">
|
||||
<field name="keyword">form_print</field>
|
||||
<field name="model">sale.sale,-1</field>
|
||||
<field name="action" ref="report_sale_internal"/>
|
||||
</record>
|
||||
<record model="ir.action.report" id="report_payment">
|
||||
<field name="name">Payment</field>
|
||||
<field name="model">account.statement.line</field>
|
||||
<field name="report_name">account.statement.line</field>
|
||||
<field name="report">optical_equipment/report/Payment.fodt</field>
|
||||
<field name="single" eval="True"/>
|
||||
</record>
|
||||
<record model="ir.action.keyword" id="report_payment_keyword">
|
||||
<field name="keyword">form_print</field>
|
||||
<field name="model">account.statement.line,-1</field>
|
||||
<field name="action" ref="report_payment"/>
|
||||
</record>
|
||||
</tryton>
|
||||
|
17
setup.py
17
setup.py
@ -69,20 +69,20 @@ if minor_version % 2:
|
||||
|
||||
setup(name=name,
|
||||
version=version,
|
||||
description='Modúlo a medida para optica',
|
||||
description='',
|
||||
long_description=read('README.rst'),
|
||||
author='OneTeam',
|
||||
author_email='info@onecluster.org',
|
||||
author='Tryton',
|
||||
author_email='bugs@tryton.org',
|
||||
url='http://www.tryton.org/',
|
||||
keywords='',
|
||||
package_dir={'trytond.modules.smart_vision': '.'},
|
||||
package_dir={'trytond.modules.optical_equipment': '.'},
|
||||
packages=(
|
||||
['trytond.modules.smart_vision']
|
||||
+ ['trytond.modules.smart_vision.%s' % p
|
||||
['trytond.modules.optical_equipment']
|
||||
+ ['trytond.modules.optical_equipment.%s' % p
|
||||
for p in find_packages()]
|
||||
),
|
||||
package_data={
|
||||
'trytond.modules.smart_vision': (info.get('xml', [])
|
||||
'trytond.modules.optical_equipment': (info.get('xml', [])
|
||||
+ ['tryton.cfg', 'view/*.xml', 'locale/*.po', '*.fodt',
|
||||
'icons/*.svg', 'tests/*.rst']),
|
||||
},
|
||||
@ -115,6 +115,7 @@ setup(name=name,
|
||||
'Natural Language :: Slovenian',
|
||||
'Natural Language :: Spanish',
|
||||
'Natural Language :: Turkish',
|
||||
'Natural Language :: Ukrainian',
|
||||
'Operating System :: OS Independent',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
@ -134,6 +135,6 @@ setup(name=name,
|
||||
zip_safe=False,
|
||||
entry_points="""
|
||||
[trytond.modules]
|
||||
smart_vision = trytond.modules.smart_vision
|
||||
optical_equipment = trytond.modules.optical_equipment
|
||||
""", # noqa: E501
|
||||
)
|
||||
|
10
shipment.xml
Normal file
10
shipment.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--This file file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tryton>
|
||||
<record model="ir.ui.view" id="shipment_out_view_form">
|
||||
<field name="model">stock.shipment.out</field>
|
||||
<field name="inherit" ref="stock.shipment_out_view_form"/>
|
||||
<field name="name">shipment_out_form</field>
|
||||
</record>
|
||||
</tryton>
|
@ -1,14 +0,0 @@
|
||||
from trytond.pool import PoolMeta
|
||||
from trytond.model import ModelSQL, ModelView, fields
|
||||
|
||||
class Subscription(metaclass=PoolMeta):
|
||||
__name__ = 'sale.subscription'
|
||||
|
||||
equipments = fields.Many2Many('sale.subscription-optical_equipment.equipment', 'subscription', 'equipment', "Equipments")
|
||||
|
||||
class SubscriptionEquipment(ModelSQL):
|
||||
'Optical Equipment - Subscription'
|
||||
__name__ = 'sale.subscription-optical_equipment.equipment'
|
||||
|
||||
subscription = fields.Many2One('sale.subscription', 'Subscription', select=True)
|
||||
equipment = fields.Many2One('optical_equipment.equipment', 'Equipment', select=True)
|
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--This file file is part of Tryton. The COPYRIGHT file at the top level of this repository contains the full copyright notices and license terms. -->
|
||||
<tryton>
|
||||
<record model="ir.ui.view" id="subscription_view_form">
|
||||
<field name="model">sale.subscription</field>
|
||||
<field name="inherit" ref="sale_subscription.subscription_view_form"/>
|
||||
<field name="name">subscription_form</field>
|
||||
</record>
|
||||
</tryton>
|
@ -2,9 +2,9 @@
|
||||
from trytond.tests.test_tryton import ModuleTestCase
|
||||
|
||||
|
||||
class SmartVisionTestCase(ModuleTestCase):
|
||||
"Test Smart Vision module"
|
||||
module = 'smart_vision'
|
||||
class OpticalEquipmentTestCase(ModuleTestCase):
|
||||
"Test Optical Equipment module"
|
||||
module = 'optical_equipment'
|
||||
|
||||
|
||||
del ModuleTestCase
|
||||
|
4
tox.ini
4
tox.ini
@ -4,8 +4,8 @@ envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
|
||||
[testenv]
|
||||
extras = test
|
||||
commands =
|
||||
coverage run --include=.*/smart_vision/* -m unittest discover -s tests
|
||||
coverage report --include=.*/smart_vision/* --omit=*/tests/*
|
||||
coverage run --include=./**/optical_equipment/* -m unittest discover -s tests
|
||||
coverage report --include=./**/optical_equipment/* --omit=*/tests/*
|
||||
deps =
|
||||
coverage
|
||||
postgresql: psycopg2 >= 2.7.0
|
||||
|
33
tryton.cfg
33
tryton.cfg
@ -1,22 +1,29 @@
|
||||
[tryton]
|
||||
version=6.0
|
||||
version=6.4
|
||||
depends:
|
||||
ir
|
||||
party
|
||||
company
|
||||
account_product
|
||||
party
|
||||
product
|
||||
product_attribute
|
||||
product_image
|
||||
product_measurements
|
||||
purchase
|
||||
sale
|
||||
stock
|
||||
country
|
||||
sale_subscription
|
||||
xml:
|
||||
party.xml
|
||||
product.xml
|
||||
measurements.xml
|
||||
equipment.xml
|
||||
sale.xml
|
||||
purchase.xml
|
||||
uom.xml
|
||||
subscription.xml
|
||||
equipment.xml
|
||||
calibration.xml
|
||||
contract.xml
|
||||
diary.xml
|
||||
agended.xml
|
||||
configuration.xml
|
||||
maintenance.xml
|
||||
move.xml
|
||||
party.xml
|
||||
uom.xml
|
||||
product.xml
|
||||
purchase.xml
|
||||
sale.xml
|
||||
balance_sale_party.xml
|
||||
shipment.xml
|
46
uom.xml
46
uom.xml
@ -27,13 +27,55 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="rounding" eval="1."/>
|
||||
<field name="digits" eval="0"/>
|
||||
</record>
|
||||
<record model="product.uom.category" id="uom_cat_frecuency">
|
||||
<record model="product.uom.category" id="uom_cat_frequency">
|
||||
<field name="name">Frequency</field>
|
||||
</record>
|
||||
<record model="product.uom" id="uom_electrical2">
|
||||
<field name="name">Hertz</field>
|
||||
<field name="symbol">Hrz</field>
|
||||
<field name="category" ref="uom_cat_frecuency"/>
|
||||
<field name="category" ref="uom_cat_frequency"/>
|
||||
<field name="rate" eval="1."/>
|
||||
<field name="factor" eval="1."/>
|
||||
<field name="rounding" eval="1."/>
|
||||
<field name="digits" eval="0"/>
|
||||
</record>
|
||||
<record model="product.uom.category" id="uom_cat_temperature">
|
||||
<field name="name">Temperature</field>
|
||||
</record>
|
||||
<record model="product.uom" id="uom_celsius">
|
||||
<field name="name">Celsius</field>
|
||||
<field name="symbol">°C</field>
|
||||
<field name="category" ref="uom_cat_temperature"/>
|
||||
<field name="rate" eval="1."/>
|
||||
<field name="factor" eval="1."/>
|
||||
<field name="rounding" eval="1."/>
|
||||
<field name="digits" eval="0"/>
|
||||
</record>
|
||||
<record model="product.uom" id="uom_fahrenheit">
|
||||
<field name="name">Fahrenheit</field>
|
||||
<field name="symbol">°F</field>
|
||||
<field name="category" ref="uom_cat_temperature"/>
|
||||
<field name="rate" eval="1."/>
|
||||
<field name="factor" eval="1."/>
|
||||
<field name="rounding" eval="1."/>
|
||||
<field name="digits" eval="0"/>
|
||||
</record>
|
||||
<record model="product.uom" id="uom_kelvin">
|
||||
<field name="name">Kelvin</field>
|
||||
<field name="symbol">°K</field>
|
||||
<field name="category" ref="uom_cat_temperature"/>
|
||||
<field name="rate" eval="1."/>
|
||||
<field name="factor" eval="1."/>
|
||||
<field name="rounding" eval="1."/>
|
||||
<field name="digits" eval="0"/>
|
||||
</record>
|
||||
<record model="product.uom.category" id="uom_cat_relative_humedity">
|
||||
<field name="name">Relative Humedity</field>
|
||||
</record>
|
||||
<record model="product.uom" id="uom_relative_humedity">
|
||||
<field name="name">Relative Humedity</field>
|
||||
<field name="symbol">%HR</field>
|
||||
<field name="category" ref="uom_cat_relative_humedity"/>
|
||||
<field name="rate" eval="1."/>
|
||||
<field name="factor" eval="1."/>
|
||||
<field name="rounding" eval="1."/>
|
||||
|
14
view/address_form.xml
Normal file
14
view/address_form.xml
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<data>
|
||||
<xpath expr="/form/field[@name='party_name']" position="after">
|
||||
<newline/>
|
||||
<label name="party_related"/>
|
||||
<field name="party_related"/>
|
||||
</xpath>
|
||||
<xpath expr="/form/group[@id='checkboxes']/field[@name='active']" position="after">
|
||||
<label name="campus"/>
|
||||
<field name="campus"/>
|
||||
</xpath>
|
||||
</data>
|
8
view/address_tree.xml
Normal file
8
view/address_tree.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<data>
|
||||
<xpath expr="//field[@name='street']" position="replace">
|
||||
<field name="street" expand="1"/>
|
||||
</xpath>
|
||||
</data>
|
16
view/assing_agended_form.xml
Normal file
16
view/assing_agended_form.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<form>
|
||||
<label name="maintenance_service"/>
|
||||
<field name="maintenance_service" colspan="3"/>
|
||||
<newline/>
|
||||
<label name="estimated_agended"/>
|
||||
<field name="estimated_agended" colspan="3" widget="date"/>
|
||||
<newline/>
|
||||
<label name="estimated_agended" string="Hora:"/>
|
||||
<field name="estimated_agended" colspan="3" widget="time"/>
|
||||
<newline/>
|
||||
<label name="technical"/>
|
||||
<field name="technical" colspan="3"/>
|
||||
</form>
|
19
view/calibration_total_tree.xml
Normal file
19
view/calibration_total_tree.xml
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tree>
|
||||
<field name="diopter" expand="1"/>
|
||||
<field name="dev_std" expand="1"/>
|
||||
<field name="uncertain_type_A" expand="1"/>
|
||||
<field name="uncertain_pattern" expand="1"/>
|
||||
<field name="k_c_calibration" expand="1"/>
|
||||
<field name="uncertain_U_b1" expand="1"/>
|
||||
<field name="d_resolution" expand="1"/>
|
||||
<field name="uncertain_U_b2_dig" expand="1"/>
|
||||
<field name="uncertain_U_b2_ana" expand="1"/>
|
||||
<field name="uncertain_combinated" expand="1"/>
|
||||
<field name="uncertain_eff" expand="1"/>
|
||||
<field name="t_student" expand="1"/>
|
||||
<field name="uncertain_expanded" expand="1"/>
|
||||
<field name="state" expand="1"/>
|
||||
</tree>
|
35
view/calibratoin_total_form.xml
Normal file
35
view/calibratoin_total_form.xml
Normal file
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<form>
|
||||
<label name="diopter"/>
|
||||
<field name="diopter"/>
|
||||
<label name="dev_std"/>
|
||||
<field name="dev_std"/>
|
||||
<label name="uncertain_type_A"/>
|
||||
<field name="uncertain_type_A"/>
|
||||
<label name="uncertain_pattern"/>
|
||||
<field name="uncertain_pattern"/>
|
||||
<label name="k_c_calibration"/>
|
||||
<field name="k_c_calibration"/>
|
||||
<label name="uncertain_U_b1"/>
|
||||
<field name="uncertain_U_b1"/>
|
||||
<label name="d_resolution"/>
|
||||
<field name="d_resolution"/>
|
||||
<label name="uncertain_U_b2_dig"/>
|
||||
<field name="uncertain_U_b2_dig"/>
|
||||
<label name="uncertain_U_b2_ana"/>
|
||||
<field name="uncertain_U_b2_ana"/>
|
||||
<label name="uncertain_combinated"/>
|
||||
<field name="uncertain_combinated"/>
|
||||
<label name="uncertain_eff"/>
|
||||
<field name="uncertain_eff"/>
|
||||
<label name="t_student"/>
|
||||
<field name="t_student"/>
|
||||
<label name="uncertain_expanded"/>
|
||||
<field name="uncertain_expanded"/>
|
||||
<label name="graph_dates"/>
|
||||
<field name="graph_dates"/>
|
||||
<label name="state"/>
|
||||
<field name="state"/>
|
||||
</form>
|
16
view/change_propietary_form.xml
Normal file
16
view/change_propietary_form.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<form>
|
||||
<label name="old_propietary"/>
|
||||
<field name="old_propietary"/>
|
||||
<newline/>
|
||||
<field name="equipments" colspan="3"/>
|
||||
<newline/>
|
||||
<label name="new_propietary"/>
|
||||
<field name="new_propietary" colspan="3"/>
|
||||
<label name="new_address"/>
|
||||
<field name="new_address" colspan="3"/>
|
||||
<label name="change_date"/>
|
||||
<field name="change_date" colspan="3"/>
|
||||
</form>
|
16
view/change_propietary_maintenance_form.xml
Normal file
16
view/change_propietary_maintenance_form.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<form>
|
||||
<label name="old_propietary"/>
|
||||
<field name="old_propietary"/>
|
||||
<newline/>
|
||||
<field name="maintenance_service" colspan="3"/>
|
||||
<newline/>
|
||||
<label name="new_propietary"/>
|
||||
<field name="new_propietary" colspan="3"/>
|
||||
<label name="new_address"/>
|
||||
<field name="new_address" colspan="3"/>
|
||||
<label name="change_date"/>
|
||||
<field name="change_date" colspan="3"/>
|
||||
</form>
|
44
view/configuration_form.xml
Normal file
44
view/configuration_form.xml
Normal file
@ -0,0 +1,44 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
|
||||
<form>
|
||||
<separator id="sequences" string="Sequences" colspan="4"/>
|
||||
<newline/>
|
||||
<label name="equipment_sequence"/>
|
||||
<field name="equipment_sequence"/>
|
||||
<newline/>
|
||||
<label name="maintenance_sequence"/>
|
||||
<field name="maintenance_sequence"/>
|
||||
<newline/>
|
||||
<label name="agended_sequence"/>
|
||||
<field name="agended_sequence"/>
|
||||
<newline/>
|
||||
<label name="contract_sequence"/>
|
||||
<field name="contract_sequence"/>
|
||||
<newline/>
|
||||
<label name="sale_quote_number"/>
|
||||
<field name="sale_quote_number"/>
|
||||
<newline/>
|
||||
<separator id="separator_configuraton" colspan="4"/>
|
||||
<separator id="environmental_conditions" string="Environmental Conditions" colspan="4"/>
|
||||
<newline/>
|
||||
<label name="temperature_min"/>
|
||||
<field name="temperature_min"/>
|
||||
<newline/>
|
||||
<label name="temperature_max"/>
|
||||
<field name="temperature_max"/>
|
||||
<newline/>
|
||||
<label name="temperature_uom"/>
|
||||
<field name="temperature_uom"/>
|
||||
<newline/>
|
||||
<label name="moisture_min"/>
|
||||
<field name="moisture_min"/>
|
||||
<newline/>
|
||||
<label name="moisture_max"/>
|
||||
<field name="moisture_max"/>
|
||||
<newline/>
|
||||
<label name="moisture_uom"/>
|
||||
<field name="moisture_uom"/>
|
||||
<newline/>
|
||||
</form>
|
7
view/confirm_sale_date_form.xml
Normal file
7
view/confirm_sale_date_form.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<form>
|
||||
<label name="sale_date"/>
|
||||
<field name="sale_date"/>
|
||||
</form>
|
47
view/contract_form.xml
Normal file
47
view/contract_form.xml
Normal file
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<form col="6">
|
||||
<label name="party"/>
|
||||
<field name="party"/>
|
||||
<label name="invoice_address"/>
|
||||
<field name="invoice_address"/>
|
||||
<label name="number"/>
|
||||
<field name="number"/>
|
||||
<newline/>
|
||||
<label name="contact"/>
|
||||
<field name="contact"/>
|
||||
<newline/>
|
||||
<label name="description"/>
|
||||
<field name="description" colspan="3"/>
|
||||
<label name="reference"/>
|
||||
<field name="reference"/>
|
||||
<newline/>
|
||||
<separator id="validity" string="Validity" colspan="6"/>
|
||||
<label name="start_date"/>
|
||||
<field name="start_date"/>
|
||||
<label name="end_date"/>
|
||||
<field name="end_date"/>
|
||||
<notebook colspan="6">
|
||||
<page string="Contracts and Prorogues" id="contracts">
|
||||
<field name="maintenance_services"/>
|
||||
</page>
|
||||
<page string="Equipments" id="equipments">
|
||||
<field name="equipments"/>
|
||||
</page>
|
||||
<page string="Other Info" id="other">
|
||||
<label name="company"/>
|
||||
<field name="company"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<label name="price_contract"/>
|
||||
<field name="price_contract"/>
|
||||
<newline/>
|
||||
<label name="state"/>
|
||||
<field name="state"/>
|
||||
<group col="2" colspan="2" id="button">
|
||||
<button name="draft"/>
|
||||
<button name="cancelled"/>
|
||||
<button name="running"/>
|
||||
</group>
|
||||
</form>
|
12
view/contract_list.xml
Normal file
12
view/contract_list.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tree>
|
||||
<field name="number"/>
|
||||
<field name="party"/>
|
||||
<field name="reference"/>
|
||||
<field name="description"/>
|
||||
<field name="start_date"/>
|
||||
<field name="end_date"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
23
view/create_contract_form.xml
Normal file
23
view/create_contract_form.xml
Normal file
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<form>
|
||||
<group id="create_contract" col="2">
|
||||
<label name="party"/>
|
||||
<field name="party"/>
|
||||
<newline/>
|
||||
<label name="invoice_address"/>
|
||||
<field name="invoice_address"/>
|
||||
<newline/>
|
||||
<label name="contact"/>
|
||||
<field name="contact"/>
|
||||
<newline/>
|
||||
<label name="start_date"/>
|
||||
<field name="start_date"/>
|
||||
<label name="end_date"/>
|
||||
<field name="end_date"/>
|
||||
<newline/>
|
||||
<label name="unit_price"/>
|
||||
<field name="unit_price"/>
|
||||
</group>
|
||||
</form>
|
24
view/diary_form.xml
Normal file
24
view/diary_form.xml
Normal file
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<form col="6">
|
||||
<label name="maintenance_service"/>
|
||||
<field name="maintenance_service"/>
|
||||
<label name="code"/>
|
||||
<field name="code"/>
|
||||
<newline/>
|
||||
<notebook colspan="6">
|
||||
<page string="Dates" id="dates_agended">
|
||||
<label name="date_expected"/>
|
||||
<field name="date_expected"/>
|
||||
<label name="date_estimated"/>
|
||||
<field name="date_estimated"/>
|
||||
<label name="date_end"/>
|
||||
<field name="date_end"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<label name="technical"/>
|
||||
<field name="technical"/>
|
||||
<label name="state"/>
|
||||
<field name="state"/>
|
||||
</form>
|
12
view/diary_tree.xml
Normal file
12
view/diary_tree.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tree>
|
||||
<field name="code"/>
|
||||
<field name="date_expected" widget="date"/>
|
||||
<field name="date_expected" string="time" widget="time"/>
|
||||
<field name="date_estimated" widget="date"/>
|
||||
<field name="date_end" widget="date"/>
|
||||
<field name="maintenance_service"/>
|
||||
<field name="technical"/>
|
||||
</tree>
|
80
view/equipment_form.xml
Normal file
80
view/equipment_form.xml
Normal file
@ -0,0 +1,80 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<form col="6">
|
||||
<label name="code"/>
|
||||
<field name="code"/>
|
||||
<label name="company"/>
|
||||
<field name="company"/>
|
||||
<label name="active"/>
|
||||
<field name="active"/>
|
||||
<newline/>
|
||||
<label name="propietary"/>
|
||||
<field name="propietary"/>
|
||||
<label name="propietary_address"/>
|
||||
<field name="propietary_address"/>
|
||||
<notebook colspan="6">
|
||||
<page string="General" id="general_equipment">
|
||||
<label name="location"/>
|
||||
<field name="location"/>
|
||||
<label name="product"/>
|
||||
<field name="product"/>
|
||||
<label name="equipment_type"/>
|
||||
<field name="equipment_type"/>
|
||||
<label name="use"/>
|
||||
<field name="use"/>
|
||||
<label name="biomedical_class"/>
|
||||
<field name="biomedical_class"/>
|
||||
<label name="calibration"/>
|
||||
<field name="calibration"/>
|
||||
<newline/>
|
||||
<label name="mark_category"/>
|
||||
<field name="mark_category"/>
|
||||
<label name="model_category"/>
|
||||
<field name="model_category"/>
|
||||
<label name="reference_category"/>
|
||||
<field name="reference_category"/>
|
||||
<label name="refurbish"/>
|
||||
<field name="refurbish"/>
|
||||
<label name="software_version"/>
|
||||
<field name="software_version"/>
|
||||
<label name="useful_life"/>
|
||||
<field name="useful_life"/>
|
||||
<label name="warranty"/>
|
||||
<field name="warranty"/>
|
||||
<newline/>
|
||||
<label name="maintenance_frequency"/>
|
||||
<field name="maintenance_frequency"/>
|
||||
<label name="serial"/>
|
||||
<field name="serial"/>
|
||||
<label name="health_register"/>
|
||||
<field name="health_register"/>
|
||||
<label name="origin_country"/>
|
||||
<field name="origin_country"/>
|
||||
</page>
|
||||
<page string="Contracts" id="contract_equipment">
|
||||
<field name="contract_history"/>
|
||||
</page>
|
||||
<page string="Maintenances" id="maintenances_equipment">
|
||||
<field name="maintenance_history"/>
|
||||
</page>
|
||||
<page string="Propietarys" id="propietarys_equipment">
|
||||
<field name="propietarys"/>
|
||||
</page>
|
||||
<page string="Origins" id="origins_equipment">
|
||||
<separator id="purchase_origin" string="Purchase Origin" colspan="4"/>
|
||||
<field name="purchase_origin"/>
|
||||
<newline/>
|
||||
<separator id="sale_destination" string="Sale Destination" colspan="4"/>
|
||||
<field name="sale_destination"/>
|
||||
<separator id="shipment_destination" string="Shipment Destination" colspan="4"/>
|
||||
<field name="shipment_destination"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<group col="2" colspan="2" id="button">
|
||||
<button name="draft"/>
|
||||
<button name="registred"/>
|
||||
</group>
|
||||
<label name="state"/>
|
||||
<field name="state"/>
|
||||
</form>
|
11
view/equipment_serial_tree.xml
Normal file
11
view/equipment_serial_tree.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms.-->
|
||||
<tree editable="1">
|
||||
<field name="code"/>
|
||||
<field name="purchase_origin"/>
|
||||
<field name="propietary"/>
|
||||
<field name="product"/>
|
||||
<field name="serial" expand="1"/>
|
||||
<button name="registred"/>
|
||||
</tree>
|
13
view/equipment_tree.xml
Normal file
13
view/equipment_tree.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms.-->
|
||||
<tree>
|
||||
<field name="code"/>
|
||||
<field name="location"/>
|
||||
<field name="propietary"/>
|
||||
<field name="propietary_address"/>
|
||||
<field name="product" expand="1"/>
|
||||
<field name="mark_category"/>
|
||||
<field name="model_category"/>
|
||||
<field name="serial"/>
|
||||
</tree>
|
7
view/maintenance_activity_form.xml
Normal file
7
view/maintenance_activity_form.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<form>
|
||||
<label name="product"/>
|
||||
<field name="product"/>
|
||||
</form>
|
6
view/maintenance_activity_tree.xml
Normal file
6
view/maintenance_activity_tree.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tree>
|
||||
<field name="product"/>
|
||||
</tree>
|
9
view/maintenance_calibracion_tree.xml
Normal file
9
view/maintenance_calibracion_tree.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms.-->
|
||||
<tree>
|
||||
<field name="value_patterns" expand="1"/>
|
||||
<field name="value_equipment" expand="1"/>
|
||||
<field name="mistake" expand="1"/>
|
||||
<field name="mistake_rate" expand="1"/>
|
||||
</tree>
|
9
view/maintenance_calibration_tree.xml
Normal file
9
view/maintenance_calibration_tree.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms.-->
|
||||
<tree>
|
||||
<field name="value_patterns" expand="1"/>
|
||||
<field name="value_equipment" expand="1"/>
|
||||
<field name="mistake" expand="1"/>
|
||||
<field name="mistake_rate" expand="1"/>
|
||||
</tree>
|
9
view/maintenance_equipment_form.xml
Normal file
9
view/maintenance_equipment_form.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<data>
|
||||
<xpath expr="/form/field[@name='maintenance_type']" position="after">
|
||||
<label name="equipment"/>
|
||||
<field name="equipment"/>
|
||||
</xpath>
|
||||
</data>
|
84
view/maintenance_form.xml
Normal file
84
view/maintenance_form.xml
Normal file
@ -0,0 +1,84 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<form>
|
||||
<label name="company"/>
|
||||
<field name="company"/>
|
||||
<label name="code"/>
|
||||
<field name="code"/>
|
||||
<label name="propietary"/>
|
||||
<field name="propietary"/>
|
||||
<label name="propietary_address"/>
|
||||
<field name="propietary_address"/>
|
||||
<label name="maintenance_type"/>
|
||||
<field name="maintenance_type"/>
|
||||
<label name="equipment"/>
|
||||
<field name="equipment"/>
|
||||
<label name="service_maintenance"/>
|
||||
<field name="service_maintenance"/>
|
||||
<label name="equipment_calibrate"/>
|
||||
<field name="equipment_calibrate"/>
|
||||
<newline/>
|
||||
<label name="description_activity"/>
|
||||
<field name="description_activity" colspan="3"/>
|
||||
<notebook colspan="6">
|
||||
<page string="Preventive" id="preventive">
|
||||
<label name="initial_operation"/>
|
||||
<field name="initial_operation"/>
|
||||
<label name="check_equipment"/>
|
||||
<field name="check_equipment"/>
|
||||
<label name="check_electric_system"/>
|
||||
<field name="check_electric_system"/>
|
||||
<label name="clean_int_ext"/>
|
||||
<field name="clean_int_ext"/>
|
||||
<label name="clean_eyes"/>
|
||||
<field name="clean_eyes"/>
|
||||
<label name="check_calibration"/>
|
||||
<field name="check_calibration"/>
|
||||
</page>
|
||||
<page string="Corrective" id="corrective">
|
||||
<field name="maintenance_lines"/>
|
||||
</page>
|
||||
<page string="Enviromental Conditions" id="enviromental_conditions_calibration">
|
||||
<group col="4" colspan="4" id="conditions">
|
||||
<label name="temperature_min"/>
|
||||
<field name="temperature_min"/>
|
||||
<newline/>
|
||||
<label name="temperature_max"/>
|
||||
<field name="temperature_max"/>
|
||||
<label name="temperature_uom"/>
|
||||
<field name="temperature_uom"/>
|
||||
<newline/>
|
||||
<label name="moisture_min"/>
|
||||
<field name="moisture_min"/>
|
||||
<newline/>
|
||||
<label name="moisture_max"/>
|
||||
<field name="moisture_max"/>
|
||||
<label name="moisture_uom"/>
|
||||
<field name="moisture_uom"/>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Calibration" id="calibration">
|
||||
<label name="patterns_equipments"/>
|
||||
<field name="patterns_equipments"/>
|
||||
<newline/>
|
||||
<group colspan="6" yexpand="1" id="lines_calibration">
|
||||
<field name="lines_calibration"/>
|
||||
<newline/>
|
||||
<field name="calibration_total"/>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Graph" id="graph">
|
||||
<field name="graph_calibration"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<newline/>
|
||||
<label name="state"/>
|
||||
<field name="state"/>
|
||||
<group id="button">
|
||||
<button name="in_progress"/>
|
||||
<button name="finished"/>
|
||||
<button name="samples"/>
|
||||
<button name="calibrate"/>
|
||||
</group>
|
||||
</form>
|
22
view/maintenance_line_form.xml
Normal file
22
view/maintenance_line_form.xml
Normal file
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<form col="6">
|
||||
<label name="line_replace"/>
|
||||
<field name="line_replace"/>
|
||||
<label name="line_maintenance_activity"/>
|
||||
<field name="line_maintenance_activity"/>
|
||||
<label name="maintenance"/>
|
||||
<field name="maintenance"/>
|
||||
<label name="replacement"/>
|
||||
<field name="replacement"/>
|
||||
<newline/>
|
||||
<label name="maintenance_activity"/>
|
||||
<field name="maintenance_activity"/>
|
||||
<newline/>
|
||||
<label name="unit"/>
|
||||
<field name="unit"/>
|
||||
<newline/>
|
||||
<label name="quantity"/>
|
||||
<field name="quantity"/>
|
||||
</form>
|
10
view/maintenance_line_tree.xml
Normal file
10
view/maintenance_line_tree.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms.-->
|
||||
<tree>
|
||||
<field name="line_replace" expand="1"/>
|
||||
<field name="line_maintenance_activity" expand="1"/>
|
||||
<field name="replacement" expand="1"/>
|
||||
<field name="maintenance_activity" expand="1"/>
|
||||
<field name="quantity"/>
|
||||
</tree>
|
20
view/maintenance_sample_form.xml
Normal file
20
view/maintenance_sample_form.xml
Normal file
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<form>
|
||||
<label name="number_sample"/>
|
||||
<field name="number_sample"/>
|
||||
<newline/>
|
||||
<label name="value_patterns"/>
|
||||
<field name="value_patterns"/>
|
||||
<label name="value_equipment"/>
|
||||
<field name="value_equipment"/>
|
||||
<label name="mistake"/>
|
||||
<field name="mistake"/>
|
||||
<label name="mistake_rate"/>
|
||||
<field name="mistake_rate"/>
|
||||
<label name="product"/>
|
||||
<field name="product" invisible="1"/>
|
||||
<label name="maintenance" />
|
||||
<field name="maintenance"/>
|
||||
</form>
|
73
view/maintenance_service_form.xml
Normal file
73
view/maintenance_service_form.xml
Normal file
@ -0,0 +1,73 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<form col="6">
|
||||
<label name="propietary"/>
|
||||
<field name="propietary"/>
|
||||
<label name="propietary_address"/>
|
||||
<field name="propietary_address"/>
|
||||
<label name="code"/>
|
||||
<field name="code"/>
|
||||
<label name="description"/>
|
||||
<field name="description" colspan="3"/>
|
||||
<label name="reference"/>
|
||||
<field name="reference"/>
|
||||
<label name="sale_origin"/>
|
||||
<field name="sale_origin"/>
|
||||
<label name="sale_date"/>
|
||||
<field name="sale_date"/>
|
||||
<label name="contract_origin"/>
|
||||
<field name="contract_origin"/>
|
||||
<label name="maintenance_type"/>
|
||||
<field name="maintenance_type"/>
|
||||
<newline/>
|
||||
<label name="temperature_min"/>
|
||||
<field name="temperature_min"/>
|
||||
<label name="temperature_max"/>
|
||||
<field name="temperature_max"/>
|
||||
<label name="temperature_uom"/>
|
||||
<field name="temperature_uom"/>
|
||||
<label name="moisture_min"/>
|
||||
<field name="moisture_min"/>
|
||||
<label name="moisture_max"/>
|
||||
<field name="moisture_max"/>
|
||||
<label name="moisture_uom"/>
|
||||
<field name="moisture_uom"/>
|
||||
<notebook colspan="6">
|
||||
<page string="General" id="general" col="2">
|
||||
<label name="technical"/>
|
||||
<field name="technical"/>
|
||||
<newline/>
|
||||
<label name="estimated_agended"/>
|
||||
<field name="estimated_agended" widget="date"/>
|
||||
<label name="estimated_agended" string="Hora"/>
|
||||
<field name="estimated_agended" widget="time"/>
|
||||
<label name="state_agended"/>
|
||||
<field name="state_agended"/>
|
||||
</page>
|
||||
<page string="Lines Of Mantenaince" id="lines_maintenance">
|
||||
<field name="lines"/>
|
||||
</page>
|
||||
<page string="Agendes" id="agendes">
|
||||
<group col="-1" id="current_agended">
|
||||
<label name="current_agended"/>
|
||||
<field name="current_agended"/>
|
||||
</group>
|
||||
<newline/>
|
||||
<field name="history_agended"/>
|
||||
</page>
|
||||
<page string="Other Info" id="other_info">
|
||||
<label name="company"/>
|
||||
<field name="company"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<newline/>
|
||||
<label name="state"/>
|
||||
<field name="state"/>
|
||||
<group id="button">
|
||||
<button name="reassing_agended" string="Reassing Agended"/>
|
||||
<button name="assing_agended" string="Assing Agended"/>
|
||||
<button name="in_progress"/>
|
||||
<button name="finished"/>
|
||||
</group>
|
||||
</form>
|
13
view/maintenance_service_tree.xml
Normal file
13
view/maintenance_service_tree.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms.-->
|
||||
<tree>
|
||||
<field name="code"/>
|
||||
<field name="maintenance_type"/>
|
||||
<field name="propietary"/>
|
||||
<field name="propietary_address"/>
|
||||
<field name="sale_origin"/>
|
||||
<field name="sale_date"/>
|
||||
<field name="technical"/>
|
||||
<field name="lines" string="# Equipments"/>
|
||||
</tree>
|
13
view/maintenance_tree.xml
Normal file
13
view/maintenance_tree.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms.-->
|
||||
<tree>
|
||||
<field name="code"/>
|
||||
<field name="maintenance_type" expand="0"/>
|
||||
<field name="service_maintenance" expand="1"/>
|
||||
<field name="propietary"/>
|
||||
<field name="propietary_address"/>
|
||||
<field name="equipment"/>
|
||||
<field name="state"/>
|
||||
<button name="finished"/>
|
||||
</tree>
|
15
view/move_form.xml
Normal file
15
view/move_form.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<data>
|
||||
<xpath expr="/form/field[@name='product']" position="after">
|
||||
<newline/>
|
||||
<label name="return_equipment"/>
|
||||
<field name="return_equipment"/>
|
||||
<newline/>
|
||||
<label name="equipment"/>
|
||||
<field name="equipment"/>
|
||||
<label name="equipment_serial"/>
|
||||
<field name="equipment_serial"/>
|
||||
</xpath>
|
||||
</data>
|
10
view/move_list_shipment.xml
Normal file
10
view/move_list_shipment.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<data>
|
||||
<xpath
|
||||
expr="//field[@name='product']" position="after">
|
||||
<field name="equipment"/>
|
||||
<field name="equipment_serial"/>
|
||||
</xpath>
|
||||
</data>
|
@ -1,42 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<form>
|
||||
<field name="subscription_history"/>
|
||||
<label name="company"/>
|
||||
<field name="company"/>
|
||||
<label name="location"/>
|
||||
<field name="location"/>
|
||||
<label name="party"/>
|
||||
<field name="party"/>
|
||||
<label name="party_address"/>
|
||||
<field name="party_address"/>
|
||||
<label name="product"/>
|
||||
<field name="product"/>
|
||||
<label name="equipment_type"/>
|
||||
<field name="equipment_type"/>
|
||||
<label name="use"/>
|
||||
<field name="use"/>
|
||||
<label name="biomedical_class"/>
|
||||
<field name="biomedical_class"/>
|
||||
<label name="calibration"/>
|
||||
<field name="calibration"/>
|
||||
<label name="mark_category"/>
|
||||
<field name="mark_category"/>
|
||||
<label name="model_category"/>
|
||||
<field name="model_category"/>
|
||||
<label name="refurbish"/>
|
||||
<field name="refurbish"/>
|
||||
<label name="software_version"/>
|
||||
<field name="software_version"/>
|
||||
<label name="useful_life"/>
|
||||
<field name="useful_life"/>
|
||||
<label name="warranty"/>
|
||||
<field name="warranty"/>
|
||||
<label name="serial"/>
|
||||
<field name="serial"/>
|
||||
<label name="health_register"/>
|
||||
<field name="health_register"/>
|
||||
<label name="origin_country"/>
|
||||
<field name="origin_country"/>
|
||||
</form>
|
@ -1,23 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tree>
|
||||
<field name="company"/>
|
||||
<field name="location"/>
|
||||
<field name="party"/>
|
||||
<field name="party_address"/>
|
||||
<field name="product"/>
|
||||
<field name="equipment_type"/>
|
||||
<field name="use"/>
|
||||
<field name="biomedical_class"/>
|
||||
<field name="calibration"/>
|
||||
<field name="mark_category"/>
|
||||
<field name="model_category"/>
|
||||
<field name="refurbish"/>
|
||||
<field name="software_version"/>
|
||||
<field name="useful_life"/>
|
||||
<field name="warranty"/>
|
||||
<field name="serial"/>
|
||||
<field name="health_register"/>
|
||||
<field name="origin_country"/>
|
||||
</tree>
|
@ -3,11 +3,7 @@
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<data>
|
||||
<xpath expr="/form/group[@id='header']" position="inside">
|
||||
<label name="client_type"/>
|
||||
<field name="client_type"/>
|
||||
</xpath>
|
||||
<xpath expr="/form/notebook/page[@id='general']" position="after">
|
||||
<page string="Equipments Party" id="equipments_party">
|
||||
</page>
|
||||
<label name="customer_type"/>
|
||||
<field name="customer_type"/>
|
||||
</xpath>
|
||||
</data>
|
||||
|
@ -1,10 +1,9 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<data>
|
||||
<xpath
|
||||
expr="/tree/field[@name='name']"
|
||||
position="before">
|
||||
<field name="client_type"/>
|
||||
expr="/tree/field[@name='name']" position="before">
|
||||
<field name="customer_type" optional="1"/>
|
||||
</xpath>
|
||||
</data>
|
||||
|
7
view/pattern_form.xml
Normal file
7
view/pattern_form.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<form>
|
||||
<label name="pattern"/>
|
||||
<field name="pattern"/>
|
||||
</form>
|
6
view/pattern_tree.xml
Normal file
6
view/pattern_tree.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tree>
|
||||
<field name="pattern"/>
|
||||
</tree>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user