Merge pull request '6.4' (#101) from 6.4 into master

Reviewed-on: #101
This commit is contained in:
Rodia 2023-07-29 21:13:58 -05:00
commit 0aace73d54
114 changed files with 48890 additions and 428 deletions

View File

View File

@ -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

View File

@ -2,4 +2,5 @@ include CHANGELOG
include COPYRIGHT
include LICENSE
include README.rst
include icons/LICENSE
graft doc

View File

@ -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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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>

0
cv.py
View File

View File

24
diary.py Normal file
View 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
View 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>

View File

@ -1,9 +1,10 @@
###################
Smart Vision Module
###################
########################
Optical Equipment Module
########################
.. toctree::
:maxdepth: 2
usage
design
releases

7
doc/releases.rst Normal file
View File

@ -0,0 +1,7 @@
.. _releases-index:
=============
Release notes
=============
.. include:: ../CHANGELOG

View File

@ -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

View File

@ -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
View 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

File diff suppressed because it is too large Load Diff

View File

@ -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
View 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>

View File

@ -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")

View File

@ -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
View 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
View 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>

View File

@ -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"))})

View File

@ -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>

View File

@ -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")

View File

@ -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>

View File

@ -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),
})]

View File

@ -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

File diff suppressed because it is too large Load Diff

1720
report/CV_Equipment.fodt Normal file

File diff suppressed because it is too large Load Diff

1979
report/Calibration.fodt Normal file

File diff suppressed because it is too large Load Diff

2080
report/Calibrations.fodt Normal file

File diff suppressed because it is too large Load Diff

1170
report/Capacitation.fodt Normal file

File diff suppressed because it is too large Load Diff

4951
report/Contract.fodt Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1435
report/Payment.fodt Normal file

File diff suppressed because it is too large Load Diff

1596
report/Purchase.fodt Normal file

File diff suppressed because it is too large Load Diff

5221
report/Sale.fodt Normal file

File diff suppressed because it is too large Load Diff

5698
report/Sale_Internal.fodt Normal file

File diff suppressed because it is too large Load Diff

1722
report/Service.fodt Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

378
sale.py
View File

@ -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()

View File

@ -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>

View File

@ -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
View 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>

View File

@ -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)

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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
View File

@ -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
View 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
View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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
View 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
View 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>

View 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
View 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
View 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
View 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>

View 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
View 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>

View 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>

View 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>

View 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>

View 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>

View 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
View 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>

View 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>

View 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>

View 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>

View 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>

View 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
View 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
View 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>

View 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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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
View 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
View 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