Compare commits
84 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 202e27aac8 | |||
| a6baf2ee59 | |||
| 00b2898408 | |||
| cbc273be00 | |||
| 0c306a8574 | |||
| c247a4720a | |||
| 111e19a33d | |||
|
|
b6e3ff5bc1 | ||
| b981dcd670 | |||
| 224c2d65e9 | |||
|
|
84cf02962a | ||
| 35eaa0554b | |||
| eb466555a0 | |||
| e5d77c2f89 | |||
| 5442a7cb0e | |||
| d040c2560e | |||
| 92113f32cf | |||
| 4019750629 | |||
| 97281a351b | |||
| b7dd21f7a6 | |||
| 659f08cbf6 | |||
| 6e40402b99 | |||
| 2538a8716c | |||
| 4bbcbec88e | |||
| a90840111b | |||
| 042ea6c796 | |||
| 6a8ebf7215 | |||
|
|
0aace73d54 | ||
| d69283f90e | |||
| 53a51aeb75 | |||
| 1c73640e95 | |||
| f3dba62675 | |||
| 65ac48edaa | |||
| bbd7f691e4 | |||
| dbcd054b3b | |||
| e1de811be3 | |||
| 216a297752 | |||
| b4e6cf0936 | |||
| c0291a0c11 | |||
| 7803f6402c | |||
| cadb113039 | |||
| 0a60a455cf | |||
| 0cb98f7622 | |||
| e1604e5e72 | |||
| 53403ba227 | |||
| 75d37438e7 | |||
| 89fc98bc01 | |||
| 3fa095f003 | |||
| fd871a8039 | |||
| 97c7d0db0c | |||
| f0d9576391 | |||
| cb9141c431 | |||
| d7a189110d | |||
| c48c49e55a | |||
| fe958b90f4 | |||
| 02e75ea907 | |||
| 52e57af7d8 | |||
| 4032460588 | |||
| 8c878949f2 | |||
| 477651227e | |||
| f372d8d496 | |||
| db8615b7a0 | |||
| ea6d5ebcbd | |||
| b3e07eff1b | |||
| fa0df0bb99 | |||
| 3551cf4f43 | |||
| dae8317b24 | |||
| e363262f49 | |||
| 2c9aba7bdc | |||
| 58cb1d7246 | |||
| 73b66669a5 | |||
| 4a92021f1f | |||
| 7cab021a5e | |||
| b387f2b10b | |||
| 35c74076b5 | |||
| 4a5f756dbe | |||
| 5818090bbf | |||
| 63f4f24f53 | |||
| 95e6ed60f3 | |||
| 48ef146c44 | |||
| b766a9ceda | |||
| f0faa4058f | |||
| 5f73e49550 | |||
| 23a6450be0 |
@@ -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
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -2,4 +2,5 @@ include CHANGELOG
|
|||||||
include COPYRIGHT
|
include COPYRIGHT
|
||||||
include LICENSE
|
include LICENSE
|
||||||
include README.rst
|
include README.rst
|
||||||
|
include icons/LICENSE
|
||||||
graft doc
|
graft doc
|
||||||
|
|||||||
70
__init__.py
70
__init__.py
@@ -1,17 +1,73 @@
|
|||||||
|
# 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 trytond.pool import Pool
|
||||||
from . import (party, product, purchase, sale,
|
from . import (agended, balance_sale_party, calibration, configuration,
|
||||||
equipment, subscription, measurements)
|
contract, company, diary, equipment, party, product,
|
||||||
|
maintenance, move, purchase, sale)
|
||||||
|
|
||||||
|
__all__ = ['register']
|
||||||
|
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
Pool.register(
|
Pool.register(
|
||||||
|
company.Employee,
|
||||||
|
equipment.OpticalEquipment,
|
||||||
|
equipment.EquipmentParty,
|
||||||
|
contract.Contract,
|
||||||
|
contract.ContractMaintenanceServices,
|
||||||
|
equipment.EquipmentContract,
|
||||||
|
equipment.EquipmentMaintenance,
|
||||||
|
equipment.ChangePropietary,
|
||||||
|
equipment.ChangeEquipment,
|
||||||
|
agended.AgendedInitial,
|
||||||
|
agended.ReAgended,
|
||||||
|
agended.ServiceMaintenanceAgended,
|
||||||
|
calibration.Calibration,
|
||||||
|
calibration.CalibrationSample,
|
||||||
|
configuration.Configuration,
|
||||||
|
diary.Diary,
|
||||||
|
contract.Cron,
|
||||||
|
contract.ContractEquipment,
|
||||||
|
contract.CreateContractInitial,
|
||||||
|
party.Address,
|
||||||
party.Party,
|
party.Party,
|
||||||
product.Template,
|
product.Template,
|
||||||
product.Product,
|
product.Product,
|
||||||
|
product.Pattern,
|
||||||
|
product.UsePattern,
|
||||||
|
product.Image,
|
||||||
purchase.Purchase,
|
purchase.Purchase,
|
||||||
purchase.Line,
|
purchase.Line,
|
||||||
|
sale.Sale,
|
||||||
|
sale.SaleDate,
|
||||||
sale.SaleLine,
|
sale.SaleLine,
|
||||||
equipment.OpticalEquipment,
|
maintenance.MaintenanceService,
|
||||||
subscription.Subscription,
|
maintenance.MaintenanceServiceLine,
|
||||||
subscription.SubscriptionEquipment,
|
maintenance.MaintenanceLine,
|
||||||
measurements.Measurements,
|
maintenance.MaintenanceActivity,
|
||||||
module='optical_equipment', type_='model')
|
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')
|
||||||
|
|||||||
144
agended.py
Normal file
144
agended.py
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
# 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, StateView, Wizard
|
||||||
|
from trytond.pool import Pool
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
diary = Diary(
|
||||||
|
code=config.agended_sequence.get(),
|
||||||
|
maintenance_service=self.start.maintenance_service,
|
||||||
|
date_expected=self.start.estimated_agended,
|
||||||
|
date_estimated=self.start.estimated_agended + timedelta(days=15),
|
||||||
|
date_end=self.start.estimated_agended + timedelta(days=15),
|
||||||
|
technical=self.start.technical.id,
|
||||||
|
state='agended',
|
||||||
|
)
|
||||||
|
diary.save()
|
||||||
|
|
||||||
|
maintenanceService = self.start.maintenance_service
|
||||||
|
maintenanceService.estimated_agended = self.start.estimated_agended
|
||||||
|
maintenanceService.technical = self.start.technical
|
||||||
|
maintenanceService.state_agended = 'agended'
|
||||||
|
maintenanceService.state = 'agended'
|
||||||
|
maintenanceService.current_agended = diary.id
|
||||||
|
maintenanceService.history_agended += (diary.id,)
|
||||||
|
maintenanceService.set_code(maintenanceService)
|
||||||
|
maintenanceService.save()
|
||||||
|
|
||||||
|
|
||||||
|
class ReAgended(ModelView):
|
||||||
|
'Agended maintenance service'
|
||||||
|
__name__ = 'optical_equipment_maintenance.reagended'
|
||||||
|
|
||||||
|
maintenance_service = fields.Many2One(
|
||||||
|
'optical_equipment_maintenance.service',
|
||||||
|
'Maintenaince Service',
|
||||||
|
required=True,
|
||||||
|
domain=[('state', '=', 'failed')],
|
||||||
|
)
|
||||||
|
estimated_agended = fields.DateTime('Date Maintenance', required=True)
|
||||||
|
technical = fields.Many2One('company.employee', 'Technical', required=True)
|
||||||
|
|
||||||
|
|
||||||
|
class ReAssingAgended(Wizard):
|
||||||
|
'Assing Agended'
|
||||||
|
__name__ = 'optical_equipment_maintenance.reassing_agended'
|
||||||
|
|
||||||
|
start = StateView(
|
||||||
|
'optical_equipment_maintenance.reagended',
|
||||||
|
'optical_equipment.reassing_agended_view_form',
|
||||||
|
[
|
||||||
|
Button('Cancel', 'end', 'tryton-cancel'),
|
||||||
|
Button('Assing', 'assing_agended', 'tryton-ok', default=True),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
assing_agended = StateAction(
|
||||||
|
'optical_equipment.act_maintenance_service_form')
|
||||||
|
|
||||||
|
def default_start(self, fields):
|
||||||
|
if len(self.records) > 0:
|
||||||
|
default = {'maintenance_service': self.records[0].id}
|
||||||
|
else:
|
||||||
|
default = {'maintenance_service': None}
|
||||||
|
return default
|
||||||
|
|
||||||
|
def do_assing_agended(self, action):
|
||||||
|
pool = Pool()
|
||||||
|
Diary = pool.get('optical_equipment_maintenance.diary')
|
||||||
|
|
||||||
|
diary = Diary(
|
||||||
|
maintenance_service=self.start.maintenance_service,
|
||||||
|
date_expected=self.start.estimated_agended,
|
||||||
|
date_estimated=self.start.estimated_agended + timedelta(days=15),
|
||||||
|
date_end=self.start.estimated_agended + timedelta(days=15),
|
||||||
|
technical=self.start.technical.id,
|
||||||
|
state='agended',
|
||||||
|
)
|
||||||
|
diary.save()
|
||||||
|
|
||||||
|
maintenanceService = self.start.maintenance_service
|
||||||
|
maintenanceService.estimated_agended = self.start.estimated_agended
|
||||||
|
maintenanceService.technical = self.start.technical
|
||||||
|
maintenanceService.state_agended = 'agended'
|
||||||
|
maintenanceService.state = 'agended'
|
||||||
|
maintenanceService.history_agended += (diary.id,)
|
||||||
|
maintenanceService.save()
|
||||||
|
|
||||||
|
|
||||||
|
class ServiceMaintenanceAgended(ModelSQL):
|
||||||
|
'Service Maintenance - Agended'
|
||||||
|
__name__ = 'optical_equipment_maintenance.service-maintenance.diary'
|
||||||
|
|
||||||
|
maintenance_service = fields.Many2One(
|
||||||
|
'optical_equipment_maintenance.service', 'Maintenance Service'
|
||||||
|
)
|
||||||
|
agended = fields.Many2One('optical_equipment_maintenance.diary', 'Agended')
|
||||||
33
agended.xml
Normal file
33
agended.xml
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
|
this repository contains the full copyright notices and license terms. -->
|
||||||
|
<tryton>
|
||||||
|
<data>
|
||||||
|
<record model="ir.ui.view" id="assing_agended_view_form">
|
||||||
|
<field name="model">optical_equipment_maintenance.agended</field>
|
||||||
|
<field name="type">form</field>
|
||||||
|
<field name="name">assing_agended_form</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.action.wizard" id="act_assing_agended">
|
||||||
|
<field name="name">Assing Agended</field>
|
||||||
|
<field name="wiz_name">optical_equipment_maintenance.assing_agended</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.ui.view" id="reassing_agended_view_form">
|
||||||
|
<field name="model">optical_equipment_maintenance.reagended</field>
|
||||||
|
<field name="type">form</field>
|
||||||
|
<field name="name">reassing_agended_form</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.action.wizard" id="act_reassing_agended">
|
||||||
|
<field name="name">ReAssing Agended</field>
|
||||||
|
<field name="wiz_name">optical_equipment_maintenance.reassing_agended</field>
|
||||||
|
</record>
|
||||||
|
<menuitem parent="menu_diary"
|
||||||
|
action="act_assing_agended"
|
||||||
|
sequence="30"
|
||||||
|
id="menu_assing_agended_form"/>
|
||||||
|
<menuitem parent="menu_diary"
|
||||||
|
action="act_reassing_agended"
|
||||||
|
sequence="40"
|
||||||
|
id="menu_reassing_agended_form"/>
|
||||||
|
</data>
|
||||||
|
</tryton>
|
||||||
163
balance_sale_party.py
Normal file
163
balance_sale_party.py
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
# 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
|
||||||
|
from trytond.transaction import Transaction
|
||||||
|
from trytond.pyson import Eval
|
||||||
|
from trytond.exceptions import UserError
|
||||||
|
|
||||||
|
__all__ = ['BalanceSalePartyStart',
|
||||||
|
'PrintBalanceSaleParty', 'BalanceSaleParty']
|
||||||
|
|
||||||
|
|
||||||
|
class BalanceSalePartyStart(ModelView):
|
||||||
|
'Balance Party Start'
|
||||||
|
__name__ = 'optical_equipment.print_balance_sale_party.start'
|
||||||
|
|
||||||
|
fiscalyear = fields.Many2One('account.fiscalyear', 'Fiscal Year',
|
||||||
|
required=True)
|
||||||
|
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 = {}
|
||||||
|
|
||||||
|
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 (not sales):
|
||||||
|
err = 'Este Tercero no Cuenta Con Ventas en Proceso ó Confirmadas.'
|
||||||
|
raise UserError(str(err))
|
||||||
|
|
||||||
|
res[id_]['sales'] = sales
|
||||||
|
|
||||||
|
report_context['records'] = res.values()
|
||||||
|
report_context['start_period'] =\
|
||||||
|
start_period.name if start_period else '*'
|
||||||
|
report_context['end_period'] = end_period.name if end_period else '*'
|
||||||
|
report_context['company'] = company
|
||||||
|
|
||||||
|
residual_amount = 0
|
||||||
|
for sale in sales:
|
||||||
|
residual_amount += sale.residual_amount
|
||||||
|
report_context['residual_amount'] = residual_amount
|
||||||
|
|
||||||
|
return report_context
|
||||||
28
balance_sale_party.xml
Normal file
28
balance_sale_party.xml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
|
this repository contains the full copyright notices and license terms. -->
|
||||||
|
<tryton>
|
||||||
|
<data>
|
||||||
|
<record model="ir.action.report" id="report_balance_sale_party">
|
||||||
|
<field name="name">Balance by Party</field>
|
||||||
|
<field name="model"></field>
|
||||||
|
<field name="report_name">optical_equipment.balance_sale_party</field>
|
||||||
|
<field name="report">optical_equipment/report/balance_sale_party.fods</field>
|
||||||
|
<field name="template_extension">ods</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.ui.view" id="print_balance_sale_party_start_view_form">
|
||||||
|
<field name="model">optical_equipment.print_balance_sale_party.start</field>
|
||||||
|
<field name="type">form</field>
|
||||||
|
<field name="name">print_balance_sale_party_start_form</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.action.wizard" id="wizard_print_balance_sale_party">
|
||||||
|
<field name="name">Print Balance Sale by Party</field>
|
||||||
|
<field name="wiz_name">optical_equipment.print_balance_sale_party</field>
|
||||||
|
</record>
|
||||||
|
<menuitem
|
||||||
|
parent="sale.menu_reporting"
|
||||||
|
action="wizard_print_balance_sale_party"
|
||||||
|
id="menu_print_balance_sale_party"
|
||||||
|
icon="tryton-print"/>
|
||||||
|
</data>
|
||||||
|
</tryton>
|
||||||
113
calibration.py
Normal file
113
calibration.py
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
# 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, sequence_ordered
|
||||||
|
from trytond.pyson import Eval, If
|
||||||
|
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',
|
||||||
|
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') is 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 self.value_patterns:
|
||||||
|
pattern = self.value_patterns.pattern
|
||||||
|
if float(pattern) < 0:
|
||||||
|
self.mistake = pattern - self.value_equipment
|
||||||
|
else:
|
||||||
|
if pattern > self.value_equipment:
|
||||||
|
self.mistake = pattern - self.value_equipment
|
||||||
|
else:
|
||||||
|
self.mistake = -pattern + self.value_equipment
|
||||||
|
|
||||||
|
if pattern == self.value_equipment:
|
||||||
|
self.mistake_rate = 0
|
||||||
|
else:
|
||||||
|
self.mistake_rate = abs(
|
||||||
|
self.mistake / pattern) * 100
|
||||||
|
|
||||||
|
|
||||||
|
class CalibrationReport(CompanyReport):
|
||||||
|
__name__ = 'optical_equipment.maintenance'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, ids, data):
|
||||||
|
with Transaction().set_context(address_with_party=True):
|
||||||
|
return super(CalibrationReport, cls).execute(ids, data)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_context(cls, records, header, data):
|
||||||
|
pool = Pool()
|
||||||
|
Date = pool.get('ir.date')
|
||||||
|
context = super().get_context(records, header, data)
|
||||||
|
context['today'] = Date.today()
|
||||||
|
|
||||||
|
return context
|
||||||
52
calibration.xml
Normal file
52
calibration.xml
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
|
this repository contains the full copyright notices and license terms. -->
|
||||||
|
<tryton>
|
||||||
|
<data>
|
||||||
|
<record model="ir.ui.view" id="maintenance_calibration_view_form">
|
||||||
|
<field name="model">optical_equipment.maintenance.calibration_sample</field>
|
||||||
|
<field name="type">form</field>
|
||||||
|
<field name="name">maintenance_sample_form</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.ui.view" id="maintenance_calibration_view_tree">
|
||||||
|
<field name="model">optical_equipment.maintenance.calibration_sample</field>
|
||||||
|
<field name="type">tree</field>
|
||||||
|
<field name="priority" eval="10"/>
|
||||||
|
<field name="name">maintenance_calibration_tree</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.ui.view" id="calibration_total_view_tree">
|
||||||
|
<field name="model">optical_equipment.maintenance.calibration</field>
|
||||||
|
<field name="type">tree</field>
|
||||||
|
<field name="name">calibration_total_tree</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.ui.view" id="calibration_total_view_form">
|
||||||
|
<field name="model">optical_equipment.maintenance.calibration</field>
|
||||||
|
<field name="type">form</field>
|
||||||
|
<field name="name">calibration_total_form</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.action.report" id="report_calibration">
|
||||||
|
<field name="name">Calibration</field>
|
||||||
|
<field name="model">optical_equipment.maintenance</field>
|
||||||
|
<field name="report_name">optical_equipment.maintenance</field>
|
||||||
|
<field name="report">optical_equipment/report/Calibration.fodt</field>
|
||||||
|
<field name="single" eval="True"/>
|
||||||
|
</record>
|
||||||
|
<record model="ir.action.keyword" id="report_calibration_keyword">
|
||||||
|
<field name="keyword">form_print</field>
|
||||||
|
<field name="model">optical_equipment.maintenance,-1</field>
|
||||||
|
<field name="action" ref="report_calibration"/>
|
||||||
|
</record>
|
||||||
|
<record model="ir.action.report" id="report_calibrations">
|
||||||
|
<field name="name">Calibrations</field>
|
||||||
|
<field name="model">optical_equipment_maintenance.service</field>
|
||||||
|
<field name="report_name">optical_equipment_maintenance.service</field>
|
||||||
|
<field name="report">optical_equipment/report/Calibrations.fodt</field>
|
||||||
|
<field name="single" eval="True"/>
|
||||||
|
</record>
|
||||||
|
<record model="ir.action.keyword" id="report_calibrations_keyword">
|
||||||
|
<field name="keyword">form_print</field>
|
||||||
|
<field name="model">optical_equipment_maintenance.service,-1</field>
|
||||||
|
<field name="action" ref="report_calibrations"/>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</tryton>
|
||||||
9
company.py
Normal file
9
company.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
from trytond.pool import PoolMeta
|
||||||
|
from trytond.model import fields
|
||||||
|
|
||||||
|
|
||||||
|
class Employee(metaclass=PoolMeta):
|
||||||
|
'Company'
|
||||||
|
__name__ = 'company.employee'
|
||||||
|
|
||||||
|
invima = fields.Char('Invima')
|
||||||
12
company.xml
Normal file
12
company.xml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?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>
|
||||||
|
<data>
|
||||||
|
<record model="ir.ui.view" id="employee_view_form">
|
||||||
|
<field name="model">company.employee</field>
|
||||||
|
<field name="inherit" ref="company.employee_view_form"/>
|
||||||
|
<field name="name">employee_form</field>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</tryton>
|
||||||
83
configuration.py
Normal file
83
configuration.py
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
from trytond.model import ModelSingleton, ModelSQL, ModelView, fields
|
||||||
|
from trytond.pyson import Id, Eval
|
||||||
|
|
||||||
|
|
||||||
|
class Configuration(ModelSingleton, ModelSQL, ModelView):
|
||||||
|
"Equipment Configuration"
|
||||||
|
__name__ = "optical_equipment.configuration"
|
||||||
|
|
||||||
|
equipment_sequence = fields.Many2One(
|
||||||
|
"ir.sequence",
|
||||||
|
"Equipment Sequence",
|
||||||
|
domain=[
|
||||||
|
("sequence_type", "=", Id(
|
||||||
|
"optical_equipment", "sequence_type_equipment"))
|
||||||
|
],
|
||||||
|
required=True
|
||||||
|
)
|
||||||
|
maintenance_sequence = fields.Many2One(
|
||||||
|
"ir.sequence",
|
||||||
|
"Maintenance Sequence",
|
||||||
|
domain=[
|
||||||
|
(
|
||||||
|
"sequence_type",
|
||||||
|
"=",
|
||||||
|
Id("optical_equipment", "sequence_type_maintenances"),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
required=True
|
||||||
|
)
|
||||||
|
sale_quote_number = fields.Many2One(
|
||||||
|
"ir.sequence",
|
||||||
|
"Sale Quote Number",
|
||||||
|
domain=[("sequence_type", "=", Id("sale", "sequence_type_sale"))],
|
||||||
|
required=True
|
||||||
|
)
|
||||||
|
agended_sequence = fields.Many2One(
|
||||||
|
"ir.sequence",
|
||||||
|
"Agended Sequence",
|
||||||
|
domain=[
|
||||||
|
("sequence_type", "=", Id(
|
||||||
|
"optical_equipment", "sequence_type_agended"))
|
||||||
|
],
|
||||||
|
required=True
|
||||||
|
)
|
||||||
|
contract_sequence = fields.Many2One(
|
||||||
|
"ir.sequence",
|
||||||
|
"Contract Sequence",
|
||||||
|
domain=[
|
||||||
|
("sequence_type", "=", Id(
|
||||||
|
"optical_equipment", "sequence_type_contract"))
|
||||||
|
],
|
||||||
|
required=True
|
||||||
|
)
|
||||||
|
temperature_min = fields.Float("Temp Min", required=True)
|
||||||
|
temperature_max = fields.Float("Temp Max", required=True)
|
||||||
|
temperature_uom = fields.Many2One(
|
||||||
|
"product.uom",
|
||||||
|
"Temperature UOM", required=True,
|
||||||
|
domain=[("category", "=", Id(
|
||||||
|
"optical_equipment", "uom_cat_temperature"))],
|
||||||
|
depends={"temperature_min"},
|
||||||
|
)
|
||||||
|
moisture_min = fields.Float("Moisture Min", required=True)
|
||||||
|
moisture_max = fields.Float("Moisture Max", required=True)
|
||||||
|
moisture_uom = fields.Many2One(
|
||||||
|
"product.uom",
|
||||||
|
"Moisture UOM",
|
||||||
|
required=True,
|
||||||
|
domain=[
|
||||||
|
("category", "=", Id(
|
||||||
|
"optical_equipment", "uom_cat_relative_humedity"))
|
||||||
|
],
|
||||||
|
depends={"moisture_min"},
|
||||||
|
)
|
||||||
|
technician_responsible = fields.Many2One(
|
||||||
|
"company.employee", "Technician Responsible",
|
||||||
|
required=True
|
||||||
|
)
|
||||||
|
invima = fields.Char(
|
||||||
|
"Invima", states={"required": Eval("technician_responsible", True)}
|
||||||
|
)
|
||||||
|
technician_signature = fields.Binary("Technician Signature",
|
||||||
|
required=True)
|
||||||
81
configuration.xml
Normal file
81
configuration.xml
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
|
this repository contains the full copyright notices and license terms. -->
|
||||||
|
<tryton>
|
||||||
|
<data>
|
||||||
|
<record model="ir.action.act_window" id="act_optical_equipment_configuration_form">
|
||||||
|
<field name="name">Configuration</field>
|
||||||
|
<field name="res_model">optical_equipment.configuration</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.ui.view" id="optical_equipment_configuration_view_form">
|
||||||
|
<field name="model">optical_equipment.configuration</field>
|
||||||
|
<field name="type">form</field>
|
||||||
|
<field name="name">configuration_form</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.action.act_window.view" id="act_optical_equipment_configuration_form_view1">
|
||||||
|
<field name="sequence" eval="10"/>
|
||||||
|
<field name="view" ref="optical_equipment_configuration_view_form"/>
|
||||||
|
<field name="act_window" ref="act_optical_equipment_configuration_form"/>
|
||||||
|
</record>
|
||||||
|
<menuitem
|
||||||
|
name="Configuration"
|
||||||
|
parent="menu_equipment"
|
||||||
|
sequence="0"
|
||||||
|
id="menu_equipment_configuration"
|
||||||
|
icon="tryton-settings"/>
|
||||||
|
<menuitem
|
||||||
|
parent="menu_equipment_configuration"
|
||||||
|
action="act_optical_equipment_configuration_form"
|
||||||
|
sequence="10"
|
||||||
|
id="menu_optical_equipment_configuration"
|
||||||
|
icon="tryton-list"/>
|
||||||
|
|
||||||
|
<record model="res.group" id="group_maintenance_admin">
|
||||||
|
<field name="name">Maintenance Administration</field>
|
||||||
|
</record>
|
||||||
|
<record model="res.user-res.group"
|
||||||
|
id="user_admin_group_maintenance_admin">
|
||||||
|
<field name="user" ref="res.user_admin"/>
|
||||||
|
<field name="group" ref="group_maintenance_admin"/>
|
||||||
|
</record>
|
||||||
|
<record model="ir.ui.menu-res.group"
|
||||||
|
id="menu_party_group_equipment_admin">
|
||||||
|
<field name="menu" ref="menu_equipment"/>
|
||||||
|
<field name="group" ref="group_equipment_admin"/>
|
||||||
|
</record>
|
||||||
|
<record model="ir.sequence.type" id="sequence_type_equipment">
|
||||||
|
<field name="name">Equipment</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.sequence.type-res.group"
|
||||||
|
id="sequence_type_equipment_group_admin">
|
||||||
|
<field name="sequence_type" ref="sequence_type_equipment"/>
|
||||||
|
<field name="group" ref="res.group_admin"/>
|
||||||
|
</record>
|
||||||
|
<record model="ir.sequence.type-res.group"
|
||||||
|
id="sequence_type_equipment_group_equipment_admin">
|
||||||
|
<field name="sequence_type" ref="sequence_type_equipment"/>
|
||||||
|
<field name="group" ref="group_equipment_admin"/>
|
||||||
|
</record>
|
||||||
|
<record model="ir.sequence" id="sequence_equipment">
|
||||||
|
<field name="name">Equipment</field>
|
||||||
|
<field name="sequence_type" ref="sequence_type_equipment"/>
|
||||||
|
</record>
|
||||||
|
<record model="ir.sequence.type" id="sequence_type_maintenances">
|
||||||
|
<field name="name">Maintenances</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.sequence.type-res.group"
|
||||||
|
id="sequence_type_maintenance_group_admin">
|
||||||
|
<field name="sequence_type" ref="sequence_type_maintenances"/>
|
||||||
|
<field name="group" ref="res.group_admin"/>
|
||||||
|
</record>
|
||||||
|
<record model="ir.sequence.type-res.group"
|
||||||
|
id="sequence_type_maintenance_group_maintenance_admin">
|
||||||
|
<field name="sequence_type" ref="sequence_type_maintenances"/>
|
||||||
|
<field name="group" ref="group_maintenance_admin"/>
|
||||||
|
</record>
|
||||||
|
<record model="ir.sequence" id="sequence_maintenances">
|
||||||
|
<field name="name">Maintenance</field>
|
||||||
|
<field name="sequence_type" ref="sequence_type_maintenances"/>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</tryton>
|
||||||
454
contract.py
Normal file
454
contract.py
Normal file
@@ -0,0 +1,454 @@
|
|||||||
|
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.exceptions import UserError
|
||||||
|
from trytond.transaction import Transaction
|
||||||
|
from trytond.wizard import Button, StateAction, StateView, Wizard
|
||||||
|
|
||||||
|
from trytond.modules.currency.fields import Monetary
|
||||||
|
from trytond.modules.product import price_digits
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
from datetime import timedelta, date
|
||||||
|
from trytond.i18n import gettext
|
||||||
|
|
||||||
|
|
||||||
|
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,
|
||||||
|
states={
|
||||||
|
'readonly': (Eval('state') != 'draft') | Eval('party', True),
|
||||||
|
},
|
||||||
|
help='Make the subscription belong to the company.',
|
||||||
|
)
|
||||||
|
number = fields.Char(
|
||||||
|
'Number', readonly=True,
|
||||||
|
help='The main identification of the subscription.'
|
||||||
|
)
|
||||||
|
reference = fields.Char(
|
||||||
|
'Reference',
|
||||||
|
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.',
|
||||||
|
)
|
||||||
|
equipment = fields.Many2One('optical_equipment.equipment', 'Equipment')
|
||||||
|
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'},
|
||||||
|
)
|
||||||
|
|
||||||
|
current_equipments = fields.Many2Many(
|
||||||
|
'optical_equipment.contract-optical_equipment.equipment',
|
||||||
|
'contract',
|
||||||
|
'equipment',
|
||||||
|
'Current Equipments',
|
||||||
|
states={'readonly': Eval('state') != 'draft'},
|
||||||
|
)
|
||||||
|
history_equipments = fields.One2Many(
|
||||||
|
'optical_equipment.equipment',
|
||||||
|
'contract',
|
||||||
|
'Equipments',
|
||||||
|
states={'readonly': Eval('state') != 'draft'},
|
||||||
|
)
|
||||||
|
currency = fields.Many2One('currency.currency', 'Currency', required=True)
|
||||||
|
price_contract = Monetary(
|
||||||
|
'Price Contract',
|
||||||
|
digits=price_digits,
|
||||||
|
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'),
|
||||||
|
('cancelled', 'draft'),
|
||||||
|
}
|
||||||
|
cls._buttons.update(
|
||||||
|
{
|
||||||
|
'draft': {
|
||||||
|
'invisible':
|
||||||
|
Eval('state').in_(['draft', 'closed'])
|
||||||
|
},
|
||||||
|
'running': {
|
||||||
|
'invisible':
|
||||||
|
Eval('state').in_(['cancelled', 'running'])
|
||||||
|
},
|
||||||
|
'closed': {
|
||||||
|
'invisible':
|
||||||
|
Eval('state').in_(['draft', 'cancelled'])
|
||||||
|
},
|
||||||
|
'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 is not 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):
|
||||||
|
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]
|
||||||
|
for equipment in contract.current_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.current_equipments:
|
||||||
|
equipment.state = 'uncontrated'
|
||||||
|
equipment.save()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
@ModelView.button
|
||||||
|
@Workflow.transition('running')
|
||||||
|
def running(cls, contracts):
|
||||||
|
contract = contracts[0]
|
||||||
|
for equipment in contract.current_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.current_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',
|
||||||
|
)
|
||||||
|
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',
|
||||||
|
)
|
||||||
|
contract = fields.Many2One(
|
||||||
|
'optical_equipment.contract',
|
||||||
|
'Contract',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
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,
|
||||||
|
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.history_equipments += tuple(equipments)
|
||||||
|
contract.current_equipments = equipments
|
||||||
|
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.state = 'draft'
|
||||||
|
contract.price_contract = dates['unit_price']
|
||||||
|
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,
|
||||||
|
current_equipments=equipments,
|
||||||
|
state='draft',
|
||||||
|
price_contract=dates['unit_price'],
|
||||||
|
)
|
||||||
|
contract.save()
|
||||||
171
contract.xml
Normal file
171
contract.xml
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
<?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>
|
||||||
|
|
||||||
|
<record model="ir.ui.icon" id="optical_equipment_contract_icon">
|
||||||
|
<field name="name">equipment_contract</field>
|
||||||
|
<field name="path">icons/file-contract-solid.svg</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<menuitem
|
||||||
|
parent="menu_equipment"
|
||||||
|
name="Contracts Management"
|
||||||
|
sequence="50"
|
||||||
|
id="menu_contracts"
|
||||||
|
icon="equipment_contract"/>
|
||||||
|
<menuitem
|
||||||
|
parent="menu_contracts"
|
||||||
|
action="act_contract_form"
|
||||||
|
sequence="30"
|
||||||
|
id="menu_contract_form"
|
||||||
|
icon="equipment_contract"/>
|
||||||
|
<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>
|
||||||
28
diary.py
Normal file
28
diary.py
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
from trytond.model import (
|
||||||
|
ModelSQL, ModelView, fields)
|
||||||
|
|
||||||
|
|
||||||
|
class Diary(ModelSQL, ModelView):
|
||||||
|
'Diary'
|
||||||
|
__name__ = 'optical_equipment_maintenance.diary'
|
||||||
|
_rec_name = 'code'
|
||||||
|
|
||||||
|
code = fields.Char("Code", 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'
|
||||||
112
diary.xml
Normal file
112
diary.xml
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
<?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>
|
||||||
|
<record model="ir.ui.icon" id="optical_equipment_schedule_icon">
|
||||||
|
<field name="name">equipment_schedule</field>
|
||||||
|
<field name="path">icons/calendar-days-solid.svg</field>
|
||||||
|
</record>
|
||||||
|
<menuitem parent="menu_equipment"
|
||||||
|
name="Diary"
|
||||||
|
sequence="10"
|
||||||
|
id="menu_diary"
|
||||||
|
icon="equipment_schedule"/>
|
||||||
|
<menuitem parent="menu_diary"
|
||||||
|
action="act_agended_list_form"
|
||||||
|
sequence="20"
|
||||||
|
id="menu_agended_list_form"
|
||||||
|
icon="equipment_schedule"/>
|
||||||
|
</data>
|
||||||
|
</tryton>
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
###################
|
########################
|
||||||
Smart Vision Module
|
Optical Equipment Module
|
||||||
###################
|
########################
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
||||||
usage
|
usage
|
||||||
design
|
design
|
||||||
|
releases
|
||||||
|
|||||||
7
doc/releases.rst
Normal file
7
doc/releases.rst
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
.. _releases-index:
|
||||||
|
|
||||||
|
=============
|
||||||
|
Release notes
|
||||||
|
=============
|
||||||
|
|
||||||
|
.. include:: ../CHANGELOG
|
||||||
587
equipment.py
587
equipment.py
@@ -1,58 +1,559 @@
|
|||||||
from collections import defaultdict
|
# 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 trytond.pool import Pool
|
||||||
from trytond.model import ModelSQL, ModelView, fields
|
from trytond.model import \
|
||||||
|
DeactivableMixin, Workflow, ModelSQL, ModelView, fields
|
||||||
|
from trytond.pyson import Eval
|
||||||
|
from trytond.transaction import Transaction
|
||||||
|
from trytond.i18n import gettext
|
||||||
from trytond.exceptions import UserError
|
from trytond.exceptions import UserError
|
||||||
|
from trytond.model.exceptions import AccessError
|
||||||
|
from trytond.wizard import Button, StateAction, 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'
|
'Optical Equipment'
|
||||||
__name__ = "optical_equipment.equipment"
|
__name__ = 'optical_equipment.equipment'
|
||||||
|
_rec_name = 'rec_name'
|
||||||
|
_order_name = 'code'
|
||||||
|
|
||||||
company = fields.Many2One('company.company', "Company")
|
_states = {
|
||||||
location = fields.Many2One('stock.location', "Location")
|
'readonly': Eval('state') != 'draft',
|
||||||
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)
|
|
||||||
|
|
||||||
subscription_history = fields.Many2Many('sale.subscription-optical_equipment.equipment', 'equipment', 'subscription', "Subscriptions")
|
_states_product = {'readonly': Eval('product', True)}
|
||||||
|
|
||||||
|
_depends = ['state']
|
||||||
|
|
||||||
|
_states_serial = {
|
||||||
|
'readonly': Eval('state') != 'draft',
|
||||||
|
}
|
||||||
|
|
||||||
|
code = fields.Char('Code', states={'readonly': True})
|
||||||
|
|
||||||
|
state = fields.Selection(
|
||||||
|
[
|
||||||
|
('draft', 'Draft'),
|
||||||
|
('registred', 'Registred'),
|
||||||
|
('uncontrated', 'UnContrated'),
|
||||||
|
('contrated', 'Contrated'),
|
||||||
|
],
|
||||||
|
'State',
|
||||||
|
required=True,
|
||||||
|
readonly=True,
|
||||||
|
sort=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
company = fields.Many2One('company.company', 'Company', readonly=True)
|
||||||
|
contract = fields.Many2One(
|
||||||
|
'optical_equipment.contract', 'Contract', ondelete='CASCADE'
|
||||||
|
)
|
||||||
|
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,
|
||||||
|
)
|
||||||
|
refurbish = fields.Boolean(
|
||||||
|
'Refurbish',
|
||||||
|
states=_states,
|
||||||
|
)
|
||||||
|
equipment_type = fields.Char('type', states=_states_product)
|
||||||
|
risk = fields.Char('Type risk', states=_states_product)
|
||||||
|
use = fields.Char('Use', states=_states_product)
|
||||||
|
biomedical_class = fields.Char('Biomedical Class', states=_states_product)
|
||||||
|
main_tecnology = fields.Char('Main tecnology', states=_states_product)
|
||||||
|
calibration = fields.Boolean('Apply calibration', states=_states_product)
|
||||||
|
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})
|
||||||
|
contract_history = fields.Function(
|
||||||
|
fields.One2Many('optical_equipment.contract',
|
||||||
|
'equipment', 'Contracts'),
|
||||||
|
'get_contracts_of_equipment',
|
||||||
|
)
|
||||||
|
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', states={'readonly': True}
|
||||||
|
)
|
||||||
|
sale_destination = fields.Reference(
|
||||||
|
'Sale Destination',
|
||||||
|
selection='get_destination', states={'readonly': True}
|
||||||
|
)
|
||||||
|
shipment_destination = fields.Reference(
|
||||||
|
'Stock Move', selection='get_shipment', states={'readonly': True}
|
||||||
|
)
|
||||||
|
rec_name = fields.Function(fields.Char('rec_name'), 'get_rec_name')
|
||||||
|
|
||||||
|
technician_responsible = fields.Function(
|
||||||
|
fields.Char('Technician Responsible'), 'get_technical'
|
||||||
|
)
|
||||||
|
invima = fields.Function(fields.Char('Invima'), 'get_invima')
|
||||||
|
|
||||||
|
del _states_serial, _states, _depends
|
||||||
|
|
||||||
|
def get_technical(self, name):
|
||||||
|
pool = Pool()
|
||||||
|
ConfigurationEquipment = pool.get('optical_equipment.configuration')
|
||||||
|
config = ConfigurationEquipment(1)
|
||||||
|
|
||||||
|
if config.technician_responsible:
|
||||||
|
technician_responsible = config.technician_responsible
|
||||||
|
return technician_responsible.party.name
|
||||||
|
|
||||||
|
def get_invima(self, name):
|
||||||
|
pool = Pool()
|
||||||
|
ConfigurationEquipment = pool.get('optical_equipment.configuration')
|
||||||
|
config = ConfigurationEquipment(1)
|
||||||
|
if config.technician_responsible.invima:
|
||||||
|
return config.technician_responsible.invima
|
||||||
|
|
||||||
|
@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
|
@staticmethod
|
||||||
def get_origin():
|
def _get_shipment():
|
||||||
return None
|
'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
|
@classmethod
|
||||||
def get_subscription_history(cls, records, names):
|
def get_shipment(cls):
|
||||||
|
IrModel = Pool().get('ir.model')
|
||||||
|
get_name = IrModel.get_name
|
||||||
|
models = cls._get_shipment()
|
||||||
|
|
||||||
|
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()
|
pool = Pool()
|
||||||
ids = []
|
Purchase = pool.get('purchase.line')
|
||||||
for record in records:
|
|
||||||
ids.append(record.id)
|
|
||||||
|
|
||||||
Subscriptions = pool.get('sale.subscription-optical_equipment.equipment')
|
return [Purchase.__name__]
|
||||||
subscriptions = Subscriptions.search([("equipment", 'in', ids)])
|
|
||||||
subscriptions_history_id = []
|
|
||||||
DICC = {}
|
|
||||||
|
|
||||||
for subscription in subscriptions:
|
@classmethod
|
||||||
DICC[subscription.equipment.id] = subscription.id
|
def get_origin(cls):
|
||||||
|
Model = Pool().get('ir.model')
|
||||||
|
get_name = Model.get_name
|
||||||
|
models = cls._get_origin()
|
||||||
|
|
||||||
#raise UserError(str(type(subscriptions_history_id[0])))
|
return [(None, '')] + [(m, get_name(m)) for m in models]
|
||||||
#raise UserError(str(list(subscriptions_history_id[0])))
|
|
||||||
#raise UserError(str(type(subscriptions_history_id)))
|
|
||||||
|
|
||||||
return DICC
|
@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 is not 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_contracts_of_equipment(self, records):
|
||||||
|
pool = Pool()
|
||||||
|
ContractsEquipment = pool.get('optical_equipment.contract')
|
||||||
|
contractsEquipment = set()
|
||||||
|
|
||||||
|
contractsEquipment = ContractsEquipment.search(
|
||||||
|
[('party', '=', self.propietary),
|
||||||
|
('history_equipments', 'in', [self.id])]
|
||||||
|
)
|
||||||
|
contracts = []
|
||||||
|
|
||||||
|
for key in contractsEquipment:
|
||||||
|
contracts.append(key.id)
|
||||||
|
|
||||||
|
return contracts
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
def get_technician_signature(self):
|
||||||
|
pool = Pool()
|
||||||
|
ConfigurationEquipment = pool.get('optical_equipment.configuration')
|
||||||
|
config = ConfigurationEquipment(1)
|
||||||
|
if config.technician_signature:
|
||||||
|
return config.technician_signature
|
||||||
|
|
||||||
|
@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 is not 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 is 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',
|
||||||
|
)
|
||||||
|
maintenance = fields.Many2One(
|
||||||
|
'optical_equipment.maintenance',
|
||||||
|
'Maintenances',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class EquipmentContract(ModelSQL, ModelView):
|
||||||
|
'Optical Equipment - Contracs Equipment'
|
||||||
|
__name__ = 'optical_equipment.contract-optical_equipment.equipment'
|
||||||
|
|
||||||
|
equipment = fields.Many2One(
|
||||||
|
'optical_equipment.equipment',
|
||||||
|
'Equipment',
|
||||||
|
)
|
||||||
|
contract = fields.Many2One(
|
||||||
|
'optical_equipment.contract',
|
||||||
|
'Contract',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class EquipmentParty(ModelSQL, ModelView):
|
||||||
|
'Optical Equipment - Party'
|
||||||
|
__name__ = 'optical_equipment.equipment-party.party'
|
||||||
|
|
||||||
|
equipment = fields.Many2One(
|
||||||
|
'optical_equipment.equipment',
|
||||||
|
'Equipment',
|
||||||
|
)
|
||||||
|
party = fields.Many2One(
|
||||||
|
'party.party',
|
||||||
|
'Party',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
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):
|
||||||
|
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
|
||||||
|
|||||||
170
equipment.xml
170
equipment.xml
@@ -3,34 +3,180 @@
|
|||||||
this repository contains the full copyright notices and license terms. -->
|
this repository contains the full copyright notices and license terms. -->
|
||||||
<tryton>
|
<tryton>
|
||||||
<data>
|
<data>
|
||||||
<menuitem
|
<record model="res.group" id="group_equipment_admin">
|
||||||
name="Equipment"
|
<field name="name">Equipment Administration</field>
|
||||||
sequence="40"
|
</record>
|
||||||
id="menu_equipment"/>
|
<record model="res.user-res.group"
|
||||||
<record model="ir.action.act_window" id="act_optical_equipment">
|
id="user_admin_group_equipment_admin">
|
||||||
|
<field name="user" ref="res.user_admin"/>
|
||||||
|
<field name="group" ref="group_equipment_admin"/>
|
||||||
|
</record>
|
||||||
|
<record model="ir.action.act_window" id="act_optical_equipment_form">
|
||||||
<field name="name">Equipments</field>
|
<field name="name">Equipments</field>
|
||||||
<field name="res_model">optical_equipment.equipment</field>
|
<field name="res_model">optical_equipment.equipment</field>
|
||||||
|
<field name="search_value"></field>
|
||||||
</record>
|
</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="model">optical_equipment.equipment</field>
|
||||||
<field name="type">tree</field>
|
<field name="type">tree</field>
|
||||||
<field name="name">optical_equipment_tree</field>
|
<field name="name">equipment_tree</field>
|
||||||
</record>
|
</record>
|
||||||
<record model="ir.ui.view" id="optical_equipment_view_form">
|
<record model="ir.ui.view" id="optical_equipment_view_form">
|
||||||
<field name="model">optical_equipment.equipment</field>
|
<field name="model">optical_equipment.equipment</field>
|
||||||
<field name="type">form</field>
|
<field name="type">form</field>
|
||||||
<field name="name">optical_equipment_form</field>
|
<field name="name">equipment_form</field>
|
||||||
</record>
|
</record>
|
||||||
<record model="ir.action.act_window.view" id="act_optical_equipment_view1">
|
<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="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>
|
||||||
<record model="ir.action.act_window.view" id="act_optical_equipment_view2">
|
<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="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>
|
||||||
<menuitem parent="menu_equipment" sequence="40" action="act_optical_equipment" id="menu_optical_equipment"/>
|
<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>
|
||||||
|
<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>
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<record model="ir.ui.icon" id="optical_equipment_serials_icon">
|
||||||
|
<field name="name">equipment_serial</field>
|
||||||
|
<field name="path">icons/barcode-solid.svg</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.ui.icon" id="optical_equipment_optical_icon">
|
||||||
|
<field name="name">optical</field>
|
||||||
|
<field name="path">icons/microscope-solid.svg</field>
|
||||||
|
</record>
|
||||||
|
<menuitem
|
||||||
|
name="Equipment"
|
||||||
|
sequence="40"
|
||||||
|
id="menu_equipment"
|
||||||
|
icon="optical"/>
|
||||||
|
<menuitem
|
||||||
|
parent="menu_equipment"
|
||||||
|
action="act_optical_equipment_form"
|
||||||
|
sequence="60"
|
||||||
|
id="menu_optical_equipment_form"
|
||||||
|
icon="optical"/>
|
||||||
|
<menuitem
|
||||||
|
parent="menu_equipment"
|
||||||
|
action="act_optical_equipment_form1"
|
||||||
|
sequence="70"
|
||||||
|
id="menu_optical_equipment_serial_form"
|
||||||
|
icon="equipment_serial"/>
|
||||||
</data>
|
</data>
|
||||||
</tryton>
|
</tryton>
|
||||||
|
|||||||
202
icons/LICENSE
Normal file
202
icons/LICENSE
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
1
icons/barcode-solid.svg
Normal file
1
icons/barcode-solid.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M24 32C10.7 32 0 42.7 0 56V456c0 13.3 10.7 24 24 24H40c13.3 0 24-10.7 24-24V56c0-13.3-10.7-24-24-24H24zm88 0c-8.8 0-16 7.2-16 16V464c0 8.8 7.2 16 16 16s16-7.2 16-16V48c0-8.8-7.2-16-16-16zm72 0c-13.3 0-24 10.7-24 24V456c0 13.3 10.7 24 24 24h16c13.3 0 24-10.7 24-24V56c0-13.3-10.7-24-24-24H184zm96 0c-13.3 0-24 10.7-24 24V456c0 13.3 10.7 24 24 24h16c13.3 0 24-10.7 24-24V56c0-13.3-10.7-24-24-24H280zM448 56V456c0 13.3 10.7 24 24 24h16c13.3 0 24-10.7 24-24V56c0-13.3-10.7-24-24-24H472c-13.3 0-24 10.7-24 24zm-64-8V464c0 8.8 7.2 16 16 16s16-7.2 16-16V48c0-8.8-7.2-16-16-16s-16 7.2-16 16z"/></svg>
|
||||||
|
After Width: | Height: | Size: 814 B |
1
icons/calendar-days-solid.svg
Normal file
1
icons/calendar-days-solid.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M128 0c17.7 0 32 14.3 32 32V64H288V32c0-17.7 14.3-32 32-32s32 14.3 32 32V64h48c26.5 0 48 21.5 48 48v48H0V112C0 85.5 21.5 64 48 64H96V32c0-17.7 14.3-32 32-32zM0 192H448V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V192zm64 80v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V272c0-8.8-7.2-16-16-16H80c-8.8 0-16 7.2-16 16zm128 0v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V272c0-8.8-7.2-16-16-16H208c-8.8 0-16 7.2-16 16zm144-16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V272c0-8.8-7.2-16-16-16H336zM64 400v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V400c0-8.8-7.2-16-16-16H80c-8.8 0-16 7.2-16 16zm144-16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V400c0-8.8-7.2-16-16-16H208zm112 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V400c0-8.8-7.2-16-16-16H336c-8.8 0-16 7.2-16 16z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.0 KiB |
1
icons/file-contract-solid.svg
Normal file
1
icons/file-contract-solid.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V160H256c-17.7 0-32-14.3-32-32V0H64zM256 0V128H384L256 0zM80 64h64c8.8 0 16 7.2 16 16s-7.2 16-16 16H80c-8.8 0-16-7.2-16-16s7.2-16 16-16zm0 64h64c8.8 0 16 7.2 16 16s-7.2 16-16 16H80c-8.8 0-16-7.2-16-16s7.2-16 16-16zm54.2 253.8c-6.1 20.3-24.8 34.2-46 34.2H80c-8.8 0-16-7.2-16-16s7.2-16 16-16h8.2c7.1 0 13.3-4.6 15.3-11.4l14.9-49.5c3.4-11.3 13.8-19.1 25.6-19.1s22.2 7.7 25.6 19.1l11.6 38.6c7.4-6.2 16.8-9.7 26.8-9.7c15.9 0 30.4 9 37.5 23.2l4.4 8.8H304c8.8 0 16 7.2 16 16s-7.2 16-16 16H240c-6.1 0-11.6-3.4-14.3-8.8l-8.8-17.7c-1.7-3.4-5.1-5.5-8.8-5.5s-7.2 2.1-8.8 5.5l-8.8 17.7c-2.9 5.9-9.2 9.4-15.7 8.8s-12.1-5.1-13.9-11.3L144 349l-9.8 32.8z"/></svg>
|
||||||
|
After Width: | Height: | Size: 942 B |
1
icons/heart-pulse-solid.svg
Normal file
1
icons/heart-pulse-solid.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M228.3 469.1L47.6 300.4c-4.2-3.9-8.2-8.1-11.9-12.4h87c22.6 0 43-13.6 51.7-34.5l10.5-25.2 49.3 109.5c3.8 8.5 12.1 14 21.4 14.1s17.8-5 22-13.3L320 253.7l1.7 3.4c9.5 19 28.9 31 50.1 31H476.3c-3.7 4.3-7.7 8.5-11.9 12.4L283.7 469.1c-7.5 7-17.4 10.9-27.7 10.9s-20.2-3.9-27.7-10.9zM503.7 240h-132c-3 0-5.8-1.7-7.2-4.4l-23.2-46.3c-4.1-8.1-12.4-13.3-21.5-13.3s-17.4 5.1-21.5 13.3l-41.4 82.8L205.9 158.2c-3.9-8.7-12.7-14.3-22.2-14.1s-18.1 5.9-21.8 14.8l-31.8 76.3c-1.2 3-4.2 4.9-7.4 4.9H16c-2.6 0-5 .4-7.3 1.1C3 225.2 0 208.2 0 190.9v-5.8c0-69.9 50.5-129.5 119.4-141C165 36.5 211.4 51.4 244 84l12 12 12-12c32.6-32.6 79-47.5 124.6-39.9C461.5 55.6 512 115.2 512 185.1v5.8c0 16.9-2.8 33.5-8.3 49.1z"/></svg>
|
||||||
|
After Width: | Height: | Size: 916 B |
1
icons/microscope-solid.svg
Normal file
1
icons/microscope-solid.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M160 32c0-17.7 14.3-32 32-32h32c17.7 0 32 14.3 32 32c17.7 0 32 14.3 32 32V288c0 17.7-14.3 32-32 32c0 17.7-14.3 32-32 32H192c-17.7 0-32-14.3-32-32c-17.7 0-32-14.3-32-32V64c0-17.7 14.3-32 32-32zM32 448H320c70.7 0 128-57.3 128-128s-57.3-128-128-128V128c106 0 192 86 192 192c0 49.2-18.5 94-48.9 128H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H320 32c-17.7 0-32-14.3-32-32s14.3-32 32-32zm80-64H304c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16z"/></svg>
|
||||||
|
After Width: | Height: | Size: 690 B |
1597
locale/es.po
Normal file
1597
locale/es.po
Normal file
File diff suppressed because it is too large
Load Diff
1114
maintenance.py
1114
maintenance.py
File diff suppressed because it is too large
Load Diff
294
maintenance.xml
Normal file
294
maintenance.xml
Normal file
@@ -0,0 +1,294 @@
|
|||||||
|
<?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="type">form</field>
|
||||||
|
<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_in_progress_button">
|
||||||
|
<field name="name">in_progress</field>
|
||||||
|
<field name="string">In progress</field>
|
||||||
|
<field name="model" search="[('model', '=', 'optical_equipment.maintenance')]"/>
|
||||||
|
</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>
|
||||||
|
<record model="ir.ui.icon" id="optical_equipment_health_icon">
|
||||||
|
<field name="name">equipment_health</field>
|
||||||
|
<field name="path">icons/heart-pulse-solid.svg</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<menuitem parent="menu_equipment"
|
||||||
|
action="act_maintenance_service_form"
|
||||||
|
sequence="20"
|
||||||
|
id="menu_maintenance_service_form"
|
||||||
|
icon="equipment_health"/>
|
||||||
|
<menuitem parent="menu_maintenance_service_form"
|
||||||
|
action="act_maintenance_form"
|
||||||
|
sequence="30"
|
||||||
|
id="menu_maintenance_form"
|
||||||
|
icon="equipment_health"/>
|
||||||
|
</data>
|
||||||
|
</tryton>
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
|
||||||
# this repository contains the full copyright notices and license terms.
|
|
||||||
from trytond.model import fields
|
|
||||||
from trytond.pool import PoolMeta
|
|
||||||
|
|
||||||
class Measurements(metaclass=PoolMeta):
|
|
||||||
__name__ = 'product.template'
|
|
||||||
|
|
||||||
temperature = fields.Float("Temperature")
|
|
||||||
temperature_uom = fields.Many2One('product.uom', "Temperature UOM")
|
|
||||||
frequency = fields.Float("Frequency")
|
|
||||||
frequency_uom = fields.Many2One('product.uom', "Frequency UOM")
|
|
||||||
wet = fields.Float("Wet")
|
|
||||||
wet_uom = fields.Many2One('product.uom', "Wet UOM")
|
|
||||||
voltageAC = fields.Float("Voltage AC")
|
|
||||||
voltageAC_uom = fields.Many2One('product.uom', "Voltage AC UOM")
|
|
||||||
voltageDC = fields.Float("Voltage DC")
|
|
||||||
voltageDC_uom = fields.Many2One('product.uom', "Voltage DC UOM")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<!--This file file is part of Tryton. The COPYRIGHT file at the top level of this repository contains the full copyright notices and license terms. -->
|
|
||||||
<tryton>
|
|
||||||
<record model="ir.ui.view" id="template_view_form">
|
|
||||||
<field name="model">product.template</field>
|
|
||||||
<field name="inherit" ref="product.template_view_form"/>
|
|
||||||
<field name="name">template_form</field>
|
|
||||||
</record>
|
|
||||||
</tryton>
|
|
||||||
16
messages.xml
Normal file
16
messages.xml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?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 grouped="1">
|
||||||
|
<record model="ir.message" id="line_without_serial">
|
||||||
|
<field name="text">La linea de envio se encuentra sin serial. Debe asignar un equipo a cada linea correspondiente.</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.message" id="msg_not_sequence_equipment">
|
||||||
|
<field name="text">Asigne una secuencia para enumerar equipos.</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.message" id="msg_finished_mantenance_service">
|
||||||
|
<field name="text">Debe finalizar las líneas de Mantenimiento Primero.</field>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</tryton>
|
||||||
404
move.py
Normal file
404
move.py
Normal file
@@ -0,0 +1,404 @@
|
|||||||
|
from trytond.model import fields, ModelView, Workflow
|
||||||
|
from trytond.modules.company import CompanyReport
|
||||||
|
from trytond.modules.company.model import 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, without_check_access
|
||||||
|
from trytond.model.exceptions import ValidationError
|
||||||
|
from trytond.i18n import gettext
|
||||||
|
|
||||||
|
from functools import wraps
|
||||||
|
|
||||||
|
|
||||||
|
def process_sale(moves_field):
|
||||||
|
def _process_sale(func):
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(cls, shipments):
|
||||||
|
pool = Pool()
|
||||||
|
Sale = pool.get('sale.sale')
|
||||||
|
transaction = Transaction()
|
||||||
|
context = transaction.context
|
||||||
|
with without_check_access():
|
||||||
|
sales = set(
|
||||||
|
m.sale
|
||||||
|
for s in cls.browse(shipments)
|
||||||
|
for m in getattr(s, moves_field)
|
||||||
|
if m.sale
|
||||||
|
)
|
||||||
|
func(cls, shipments)
|
||||||
|
if sales:
|
||||||
|
with transaction.set_context(
|
||||||
|
queue_batch=context.get('queue_batch', True)
|
||||||
|
):
|
||||||
|
Sale.__queue__.process(sales)
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
return _process_sale
|
||||||
|
|
||||||
|
|
||||||
|
class Move(metaclass=PoolMeta):
|
||||||
|
'Stock Move'
|
||||||
|
__name__ = 'stock.move'
|
||||||
|
|
||||||
|
_states = {
|
||||||
|
'invisible': ~Eval('product_equipment'),
|
||||||
|
'readonly': (Eval('state').in_(['cancelled', 'done'])),
|
||||||
|
}
|
||||||
|
|
||||||
|
product_equipment = fields.Function(
|
||||||
|
fields.Boolean('It Equipment'), 'get_product_equipment'
|
||||||
|
)
|
||||||
|
|
||||||
|
return_equipment = fields.Boolean(
|
||||||
|
'Devolución',
|
||||||
|
states=_states)
|
||||||
|
|
||||||
|
equipment = fields.Many2One(
|
||||||
|
'optical_equipment.equipment',
|
||||||
|
'Equipment',
|
||||||
|
domain=[
|
||||||
|
If(
|
||||||
|
Eval('return_equipment', True),
|
||||||
|
('state', 'in', ['uncontrated', 'contrated']),
|
||||||
|
('state', '=', 'registred'),
|
||||||
|
),
|
||||||
|
('product', '=', Eval('product')),
|
||||||
|
],
|
||||||
|
states=_states,
|
||||||
|
depends=['product_equipment'],
|
||||||
|
)
|
||||||
|
equipment_serial = fields.Function(
|
||||||
|
fields.Char(
|
||||||
|
'Serial',
|
||||||
|
states=_states,
|
||||||
|
depends=['product_equipment'],
|
||||||
|
),
|
||||||
|
'get_equipment_serial',
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def __setup__(cls):
|
||||||
|
super(Move, cls).__setup__()
|
||||||
|
cls.origin.states['required'] = False
|
||||||
|
|
||||||
|
@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('equipment', 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')
|
||||||
|
@process_sale('outgoing_moves')
|
||||||
|
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 not move.equipment:
|
||||||
|
count += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
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', '=', 'Customer'])[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()
|
||||||
|
|
||||||
|
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])
|
||||||
|
iterator = groupby(shipments, key=lambda s: s.company)
|
||||||
|
for company, c_shipments in iterator:
|
||||||
|
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')
|
||||||
|
|
||||||
|
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:
|
||||||
|
shipment.service_maintenance_initial = True
|
||||||
|
shipment.save()
|
||||||
|
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 not serial:
|
||||||
|
error = 'Por favor Primero debe Asignar'
|
||||||
|
+ 'un serial a todos los Equipos.'
|
||||||
|
raise UserError(str(error))
|
||||||
|
|
||||||
|
for move in shipment.inventory_moves:
|
||||||
|
valid = \
|
||||||
|
move.product_equipment \
|
||||||
|
and move.equipment \
|
||||||
|
and move.equipment.product.template.maintenance_required
|
||||||
|
|
||||||
|
if (not valid):
|
||||||
|
continue
|
||||||
|
|
||||||
|
template = move.equipment.product.template
|
||||||
|
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=template.check_equipment,
|
||||||
|
check_electric_system=template.check_electric_system,
|
||||||
|
clean_int_ext=template.clean_int_ext,
|
||||||
|
clean_eyes=template.clean_eyes,
|
||||||
|
check_calibration=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()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
@ModelView.button
|
||||||
|
@Workflow.transition('picked')
|
||||||
|
@set_employee('picked_by')
|
||||||
|
def pick(cls, shipments):
|
||||||
|
super(ShipmentOut, cls).pick(shipments)
|
||||||
|
for shipment in shipments:
|
||||||
|
for line in shipment.inventory_moves:
|
||||||
|
if line.product.equipment and not line.equipment:
|
||||||
|
raise ValidationError(
|
||||||
|
gettext("optical_equipment.line_without_serial"))
|
||||||
|
|
||||||
|
|
||||||
|
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')
|
||||||
|
Move.do([m for s in shipments for m in s.incoming_moves])
|
||||||
|
for s in shipments:
|
||||||
|
for m in s.incoming_moves:
|
||||||
|
if not m.equipment:
|
||||||
|
continue
|
||||||
|
|
||||||
|
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
|
||||||
44
move.xml
Normal file
44
move.xml
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<?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>
|
||||||
|
<data>
|
||||||
|
<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>
|
||||||
|
</data>
|
||||||
|
</tryton>
|
||||||
31
party.py
31
party.py
@@ -1,11 +1,28 @@
|
|||||||
from trytond.pool import PoolMeta
|
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
from trytond.model import ModelSQL, ModelView, fields
|
# this repository contains the full copyright notices and license terms.
|
||||||
from . import equipment
|
|
||||||
|
from trytond.pool import PoolMeta
|
||||||
|
from trytond.model import fields
|
||||||
|
from trytond.pyson import Eval
|
||||||
|
|
||||||
|
|
||||||
|
_CUSTOMER_TYPE = [("ips", "IPS"), ("optica", "Optica"), ("otro", "Otro")]
|
||||||
|
|
||||||
_CLIENT_TYPE = [('ips', 'IPS'),
|
|
||||||
('optica', 'Optica')]
|
|
||||||
|
|
||||||
class Party(metaclass=PoolMeta):
|
class Party(metaclass=PoolMeta):
|
||||||
__name__ = 'party.party'
|
__name__ = "party.party"
|
||||||
|
|
||||||
client_type = fields.Selection(_CLIENT_TYPE, 'Client type')
|
customer_type = fields.Selection(_CUSTOMER_TYPE, "Customer Type")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def default_customer_type(csl):
|
||||||
|
return "otro"
|
||||||
|
|
||||||
|
|
||||||
|
class Address(metaclass=PoolMeta):
|
||||||
|
__name__ = "party.address"
|
||||||
|
|
||||||
|
campus = fields.Boolean("Campus")
|
||||||
|
party_related = fields.Many2One(
|
||||||
|
"party.party", "Party Related", states={"invisible": (~Eval("campus"))}
|
||||||
|
)
|
||||||
|
|||||||
23
party.xml
23
party.xml
@@ -2,14 +2,27 @@
|
|||||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
<!-- 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. -->
|
||||||
<tryton>
|
<tryton>
|
||||||
<record model="ir.ui.view" id="party_view_form">
|
<data>
|
||||||
<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">
|
<record model="ir.ui.view" id="party_view_tree">
|
||||||
<field name="model">party.party</field>
|
<field name="model">party.party</field>
|
||||||
<field name="inherit" ref="party.party_view_tree"/>
|
<field name="inherit" ref="party.party_view_tree"/>
|
||||||
<field name="name">party_tree</field>
|
<field name="name">party_tree</field>
|
||||||
</record>
|
</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>
|
||||||
|
</data>
|
||||||
</tryton>
|
</tryton>
|
||||||
|
|||||||
557
product.py
557
product.py
@@ -1,108 +1,503 @@
|
|||||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
#txhis repository contains the full copyright notices and license terms
|
# this repository contains the full copyright notices and license terms
|
||||||
from sql import Literal
|
|
||||||
from sql.operators import Equal
|
|
||||||
|
|
||||||
from trytond.pool import Pool, PoolMeta
|
from trytond.pool import Pool, PoolMeta
|
||||||
from trytond.model import (
|
from trytond.model import ModelView, ModelSQL, fields
|
||||||
ModelView, ModelSQL, fields, Exclude)
|
from trytond.pyson import Bool, If, Eval, Id
|
||||||
from trytond.pyson import If, Eval
|
|
||||||
|
|
||||||
|
|
||||||
|
_RISK = [
|
||||||
|
("n/a", "No aplíca"),
|
||||||
|
("uno", "I"),
|
||||||
|
("dosA", "IIA"),
|
||||||
|
("dosB", "IIB")]
|
||||||
|
|
||||||
|
_USE = [
|
||||||
|
("", ""),
|
||||||
|
("medico", "Médico"),
|
||||||
|
("basico", "Basico"),
|
||||||
|
("apoyo", "Apoyo")]
|
||||||
|
|
||||||
_RISK = [('uno', 'I'),
|
_BIOMEDICAL_CLASS = [
|
||||||
('dosA', 'IIA'),
|
("n/a", "No aplíca"),
|
||||||
('dosB', 'IIB')]
|
("diagnostico", "Diagnóstico"),
|
||||||
|
("rehabilitación", "Rehabilitación"),
|
||||||
|
]
|
||||||
|
|
||||||
_USE = [('medico', 'Médico'),
|
_MAIN_TECNOLOGY = [
|
||||||
('basico', 'Basico'),
|
("", ""),
|
||||||
('apoyo', 'Apoyo')]
|
("mecanico", "Mecánico"),
|
||||||
|
("electrico", "Electrico"),
|
||||||
|
("electronico", "Electrónico"),
|
||||||
|
("hidraulico", "Hidraulico"),
|
||||||
|
("neumatico", "Neumatico"),
|
||||||
|
]
|
||||||
|
|
||||||
_BIOMEDICAL_CLASS = [('diagnostico', 'Diagnóstico'),
|
_EQUIPMENT_TYPE = [
|
||||||
('rehabilitación', 'Rehabilitación')]
|
("", ""),
|
||||||
|
("mobiliario_optico", "Mobiliario óptico"),
|
||||||
|
("refraccion", "Refracción"),
|
||||||
|
("medico", "Medicion"),
|
||||||
|
("accesorios", "Accesorios"),
|
||||||
|
]
|
||||||
|
|
||||||
_MAIN_TECNOLOGY = [('mecanico', 'Mecánico'),
|
NON_MEASURABLE = ["service"]
|
||||||
('electrico', 'Electrico'),
|
|
||||||
('electronico', 'Electrónico'),
|
|
||||||
('hidraulico', 'Hidraulico'),
|
|
||||||
('neumatico', 'Neumatico')]
|
|
||||||
|
|
||||||
_EQUIPMENT_TYPE = [('mobiliario_optico', 'Mobiliario óptico'),
|
|
||||||
('refraccion', 'Refracción'),
|
|
||||||
('medico', 'Medicion'),
|
|
||||||
('accesorios', 'Accesorios')]
|
|
||||||
|
|
||||||
|
|
||||||
class Template(metaclass=PoolMeta):
|
class Template(metaclass=PoolMeta):
|
||||||
'Template'
|
"Template"
|
||||||
__name__ = 'product.template'
|
__name__ = "product.template"
|
||||||
|
|
||||||
equipment = fields.Boolean('It is equipment')
|
product = fields.Many2One(
|
||||||
equipment_type = fields.Selection(_EQUIPMENT_TYPE, 'Equipment type')
|
"optical_equipment.maintenance",
|
||||||
risk = fields.Selection(_RISK, 'Type risk')
|
"Maintenance Activity",
|
||||||
use = fields.Selection(_USE, 'Use')
|
ondelete="CASCADE",
|
||||||
biomedical_class = fields.Selection(_BIOMEDICAL_CLASS,
|
)
|
||||||
'Biomedical Class')
|
equipment = fields.Boolean(
|
||||||
main_tecnology = fields.Selection(_MAIN_TECNOLOGY,
|
"It is equipment",
|
||||||
'Main tecnology')
|
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),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
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",
|
||||||
|
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")
|
calibration = fields.Boolean("Apply calibration")
|
||||||
observation = fields.Text('Observation')
|
observation = fields.Text("Observation")
|
||||||
mark_category = fields.Many2One('product.category', 'Mark')
|
|
||||||
model_category = fields.Many2One('product.category', "Model")
|
# Mark, Category, Reference
|
||||||
reference = fields.Char("Reference", size=None)
|
mark_category = fields.Many2One(
|
||||||
origin_country = fields.Many2One('country.country',"Origin Country")
|
"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",
|
||||||
|
states={
|
||||||
|
"required": (Eval("equipment", True))
|
||||||
|
},
|
||||||
|
domain=[("parent", "=", Eval("model_category"))])
|
||||||
|
|
||||||
|
# Information Equipment
|
||||||
|
origin_country = fields.Many2One("country.country", "Origin Country")
|
||||||
|
refurbish = fields.Boolean("Refurbish")
|
||||||
|
software_required = fields.Boolean("Software Required")
|
||||||
software_version = fields.Char(
|
software_version = fields.Char(
|
||||||
"Software version", size=None)
|
"Software version",
|
||||||
useful_life = fields.Char(
|
states={"invisible": ~Eval("software_required", True)},
|
||||||
"Useful life", size=None)
|
depends={"software_required"},
|
||||||
warranty = fields.Char(
|
)
|
||||||
"Warranty", size=None)
|
|
||||||
serial = fields.Char(
|
|
||||||
"Serial", size=None)
|
|
||||||
health_register = fields.Char(
|
|
||||||
"Health_Register", size=None)
|
|
||||||
refurbish = fields.Boolean('Refurbish')
|
|
||||||
|
|
||||||
@staticmethod
|
# These are measurements required for the equipments, are in this place
|
||||||
def default_equipment():
|
# for manage of class 'product.template'
|
||||||
return False
|
|
||||||
|
|
||||||
@staticmethod
|
temperature_min = fields.Float("Temp Min")
|
||||||
def default_risk():
|
temperature_max = fields.Float("Temp Max")
|
||||||
return None
|
temperature_uom = fields.Many2One(
|
||||||
|
"product.uom",
|
||||||
|
"Temperature UOM",
|
||||||
|
domain=[
|
||||||
|
("category", "=", Id("optical_equipment", "uom_cat_temperature"))],
|
||||||
|
states={'invisible': (~Eval('temperature_min', True))}
|
||||||
|
)
|
||||||
|
frequency = fields.Float("Frequency")
|
||||||
|
frequency_uom = fields.Many2One(
|
||||||
|
"product.uom",
|
||||||
|
"Frequency UOM",
|
||||||
|
domain=[
|
||||||
|
("category", "=", Id("optical_equipment", "uom_cat_frequency"))],
|
||||||
|
states={'invisible': (Eval('frequency', 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': (~Eval('moisture_min', 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': (~Eval('frequency', 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': (~Eval('voltageAC', 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': (
|
||||||
|
~Eval('voltageDC', True) | ~Eval(
|
||||||
|
'electrical_equipment', True))},)
|
||||||
|
useful_life = fields.Integer("Useful life")
|
||||||
|
warranty = fields.Integer("Warranty")
|
||||||
|
|
||||||
@staticmethod
|
# calibration parameters
|
||||||
def default_use():
|
use_pattern = fields.Many2One(
|
||||||
return None
|
"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)},
|
||||||
|
)
|
||||||
|
|
||||||
@staticmethod
|
d_resolution = fields.Float(
|
||||||
def default_biomedical_class():
|
"Resolution d",
|
||||||
return None
|
states={
|
||||||
|
'invisible': (Eval('resolution_type') != 'digital'),
|
||||||
|
'required': (Eval('resolution_type') == 'digital')
|
||||||
|
})
|
||||||
|
analog_resolution = fields.Float(
|
||||||
|
"Analog resolution",
|
||||||
|
states={'invisible': (Eval('resolution_type') != 'analoga'), },
|
||||||
|
)
|
||||||
|
a_factor_resolution = fields.Float(
|
||||||
|
"(a) Resolution",
|
||||||
|
states={'invisible': (Eval('resolution_type') != 'analoga')},
|
||||||
|
)
|
||||||
|
Usubi = fields.Integer("Usub i", states={
|
||||||
|
"required": Eval("calibration", False)})
|
||||||
|
|
||||||
@staticmethod
|
# maintenance activities
|
||||||
def default_main_tecnology():
|
initial_operation = fields.Boolean(
|
||||||
return None
|
"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")
|
||||||
|
|
||||||
@staticmethod
|
# Maintenance activites Preventives
|
||||||
def default_calibration():
|
preventive_activities = fields.Text("Preventive Activities")
|
||||||
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
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def view_attributes(cls):
|
def view_attributes(cls):
|
||||||
return super(Template, cls).view_attributes() + [
|
return super(Template, cls).view_attributes() + [
|
||||||
('//page[@id="features"]', 'states', {
|
(
|
||||||
'invisible': ~Eval('equipment'),
|
"//page[@id='features']",
|
||||||
})]
|
"states",
|
||||||
|
{
|
||||||
|
"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
|
||||||
|
|
||||||
|
@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):
|
class Product(metaclass=PoolMeta):
|
||||||
__name__ = 'product.product'
|
__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 = "rec_name"
|
||||||
|
|
||||||
|
product = fields.Many2One(
|
||||||
|
"product.template", "Template", ondelete="CASCADE")
|
||||||
|
pattern = fields.Float("Value Pattern")
|
||||||
|
rec_name = fields.Function(fields.Char("rec_name"), "get_rec_name")
|
||||||
|
|
||||||
|
@fields.depends("pattern")
|
||||||
|
def get_rec_name(self, name):
|
||||||
|
if self.pattern:
|
||||||
|
return str(self.pattern)
|
||||||
|
|||||||
69
product.xml
69
product.xml
@@ -3,15 +3,76 @@
|
|||||||
this repository contains the full copyright notices and license terms. -->
|
this repository contains the full copyright notices and license terms. -->
|
||||||
<tryton>
|
<tryton>
|
||||||
<data>
|
<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">
|
<record model="ir.ui.view" id="template_view_form1">
|
||||||
<field name="model">product.template</field>
|
<field name="model">product.template</field>
|
||||||
<field name="inherit" ref="product.template_view_form"/>
|
<field name="inherit" ref="product.template_view_form"/>
|
||||||
<field name="name">template_form</field>
|
<field name="name">template_form</field>
|
||||||
</record>
|
</record>
|
||||||
<record model="ir.ui.view" id="template_view_tree1">
|
<!-- <record model="ir.ui.view" id="template_view_tree1"> -->
|
||||||
<field name="model">product.template</field>
|
<!-- <field name="model">product.template</field> -->
|
||||||
<field name="inherit" ref="product.template_view_tree"/>
|
<!-- <field name="inherit" ref="product.template_view_tree"/> -->
|
||||||
<field name="name">template_tree</field>
|
<!-- <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>
|
</record>
|
||||||
</data>
|
</data>
|
||||||
</tryton>
|
</tryton>
|
||||||
|
|||||||
238
purchase.py
238
purchase.py
@@ -1,72 +1,220 @@
|
|||||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
# txhis repository contains the full copyright notices and license terms
|
# txhis repository contains the full copyright notices and license terms
|
||||||
from trytond.pool import Pool, PoolMeta
|
from trytond.pool import Pool, PoolMeta
|
||||||
from trytond.model import ModelView, ModelSQL, fields
|
from trytond.model import ModelView, fields
|
||||||
|
from trytond.modules.product import round_price
|
||||||
|
from trytond.pyson import Eval, If, Bool
|
||||||
from trytond.exceptions import UserError
|
from trytond.exceptions import UserError
|
||||||
|
from trytond.transaction import Transaction
|
||||||
|
|
||||||
|
|
||||||
class Purchase(metaclass=PoolMeta):
|
class Purchase(metaclass=PoolMeta):
|
||||||
__name__ = 'purchase.purchase'
|
"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
|
@classmethod
|
||||||
@ModelView.button
|
@ModelView.button
|
||||||
def process(cls, purchases):
|
def create_equipments(cls, purchases):
|
||||||
|
if len(purchases) == 1:
|
||||||
pool = Pool()
|
pool = Pool()
|
||||||
Equipment = pool.get('optical_equipment.equipment')
|
Equipment = pool.get("optical_equipment.equipment")
|
||||||
#raise UserError(str(type(Equipment)))
|
|
||||||
Line = pool.get('purchase.line')
|
purchase = purchases[0]
|
||||||
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()
|
|
||||||
for line in purchase.lines:
|
for line in purchase.lines:
|
||||||
#raise UserError(str(dir(line)))
|
if not line.product.equipment:
|
||||||
|
continue
|
||||||
|
|
||||||
|
for i in range(0, int(line.quantity)):
|
||||||
equipment = Equipment(
|
equipment = Equipment(
|
||||||
company=line.company,
|
company=line.company,
|
||||||
|
location=line.to_location,
|
||||||
equipment_type=line.product.equipment_type,
|
equipment_type=line.product.equipment_type,
|
||||||
party_address=line.address_equipment,
|
propietary=line.company.party,
|
||||||
|
propietary_address=line.address_equipment,
|
||||||
product=line.product,
|
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,
|
risk=line.product.risk,
|
||||||
|
origin_country=line.product.origin_country,
|
||||||
use=line.product.use,
|
use=line.product.use,
|
||||||
biomedical_class=line.product.biomedical_class,
|
biomedical_class=line.product.biomedical_class,
|
||||||
calibration=line.product.calibration,
|
|
||||||
refurbish=line.refurbish,
|
refurbish=line.refurbish,
|
||||||
serial=line.serial_equipment,
|
serial=(None if line.quantity > 1
|
||||||
software_version=line.product.software_version,
|
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()
|
equipment.save()
|
||||||
#raise UserError(str([equipment.serial, equipment.software_version]))
|
|
||||||
""" line.set_actual_quantity()
|
|
||||||
lines.append(line)
|
|
||||||
|
|
||||||
if purchase.is_done():
|
purchase.equipment_create = True
|
||||||
if purchase.state != 'done':
|
cls.save(purchases)
|
||||||
if purchase.state == 'confirmed':
|
else:
|
||||||
process.append(purchase)
|
raise UserError(str("Número de Compras Invalido."))
|
||||||
done.append(purchase)
|
|
||||||
elif purchase.state != 'processing':
|
|
||||||
process.append(purchase)
|
|
||||||
Line.save(lines)
|
|
||||||
if process:
|
|
||||||
cls.proceed(process)
|
|
||||||
if done:
|
|
||||||
cls.do(done)"""
|
|
||||||
|
|
||||||
class Line(metaclass=PoolMeta):
|
class Line(metaclass=PoolMeta):
|
||||||
__name__ = 'purchase.line'
|
"Purchase Line Equipment"
|
||||||
|
__name__ = "purchase.line"
|
||||||
|
|
||||||
address_equipment = fields.Many2One('party.address', "Direccion")
|
origin_country = fields.Many2One("country.country", "Origin Country")
|
||||||
serial_equipment = fields.Char("Serial", size=None, required=True)
|
address_equipment = fields.Many2One(
|
||||||
|
"party.address", "Direccion", required=True)
|
||||||
|
serial_equipment = fields.Char(
|
||||||
|
"Serial",
|
||||||
|
size=None,
|
||||||
|
# states={'invisible': Decimal(Eval('quantity')) > 1}
|
||||||
|
)
|
||||||
refurbish = fields.Boolean("Refurbish")
|
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 and (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),
|
||||||
|
})]
|
||||||
|
|||||||
30
purchase.xml
30
purchase.xml
@@ -3,10 +3,40 @@
|
|||||||
this repository contains the full copyright notices and license terms. -->
|
this repository contains the full copyright notices and license terms. -->
|
||||||
<tryton>
|
<tryton>
|
||||||
<data>
|
<data>
|
||||||
|
<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">
|
<record model="ir.ui.view" id="purchase_line_view_form">
|
||||||
<field name="model">purchase.line</field>
|
<field name="model">purchase.line</field>
|
||||||
<field name="inherit" ref="purchase.purchase_line_view_form"/>
|
<field name="inherit" ref="purchase.purchase_line_view_form"/>
|
||||||
<field name="name">purchase_line_form</field>
|
<field name="name">purchase_line_form</field>
|
||||||
</record>
|
</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>
|
</data>
|
||||||
</tryton>
|
</tryton>
|
||||||
|
|||||||
2044
report/CVS_Equipments.fodt
Normal file
2044
report/CVS_Equipments.fodt
Normal file
File diff suppressed because it is too large
Load Diff
1850
report/CV_Equipment.fodt
Normal file
1850
report/CV_Equipment.fodt
Normal file
File diff suppressed because it is too large
Load Diff
2121
report/Calibration.fodt
Normal file
2121
report/Calibration.fodt
Normal file
File diff suppressed because it is too large
Load Diff
2172
report/Calibrations.fodt
Normal file
2172
report/Calibrations.fodt
Normal file
File diff suppressed because it is too large
Load Diff
1170
report/Capacitation.fodt
Normal file
1170
report/Capacitation.fodt
Normal file
File diff suppressed because it is too large
Load Diff
4957
report/Contract.fodt
Normal file
4957
report/Contract.fodt
Normal file
File diff suppressed because it is too large
Load Diff
4761
report/Delivery_Certificated.fodt
Normal file
4761
report/Delivery_Certificated.fodt
Normal file
File diff suppressed because it is too large
Load Diff
1880
report/Maintenance_History.fodt
Normal file
1880
report/Maintenance_History.fodt
Normal file
File diff suppressed because it is too large
Load Diff
1805
report/Maintenance_Service.fodt
Normal file
1805
report/Maintenance_Service.fodt
Normal file
File diff suppressed because it is too large
Load Diff
1671
report/Maintenance_Timeline.fodt
Normal file
1671
report/Maintenance_Timeline.fodt
Normal file
File diff suppressed because it is too large
Load Diff
2061
report/Maintenances_Historys.fodt
Normal file
2061
report/Maintenances_Historys.fodt
Normal file
File diff suppressed because it is too large
Load Diff
1430
report/Payment.fodt
Normal file
1430
report/Payment.fodt
Normal file
File diff suppressed because it is too large
Load Diff
4872
report/Prorrogation.fodt
Normal file
4872
report/Prorrogation.fodt
Normal file
File diff suppressed because it is too large
Load Diff
1596
report/Purchase.fodt
Normal file
1596
report/Purchase.fodt
Normal file
File diff suppressed because it is too large
Load Diff
5221
report/Sale.fodt
Normal file
5221
report/Sale.fodt
Normal file
File diff suppressed because it is too large
Load Diff
5695
report/Sale_Internal.fodt
Normal file
5695
report/Sale_Internal.fodt
Normal file
File diff suppressed because it is too large
Load Diff
2589
report/Service.fodt
Normal file
2589
report/Service.fodt
Normal file
File diff suppressed because it is too large
Load Diff
1207
report/balance_sale_party.fods
Normal file
1207
report/balance_sale_party.fods
Normal file
File diff suppressed because it is too large
Load Diff
388
sale.py
388
sale.py
@@ -1,21 +1,387 @@
|
|||||||
from trytond.pool import Pool, PoolMeta
|
from trytond.pool import Pool, PoolMeta
|
||||||
from trytond.model import ModelView, ModelSQL, fields
|
from trytond.model import ModelView, fields
|
||||||
|
from trytond.pyson import Eval, If
|
||||||
|
from decimal import Decimal
|
||||||
|
from trytond.transaction import Transaction
|
||||||
|
from trytond.model import Workflow
|
||||||
|
from trytond.modules.company.model import (
|
||||||
|
set_employee)
|
||||||
|
|
||||||
|
from trytond.exceptions import UserError
|
||||||
|
from trytond.wizard import (
|
||||||
|
Button, StateAction, StateView, Wizard)
|
||||||
|
from trytond.i18n import gettext
|
||||||
|
from trytond.modules.sale.exceptions import PartyLocationError
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
|
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')})
|
||||||
|
payment_term_description = fields.Char("Payment Term", states={
|
||||||
|
'readonly': Eval('state') != 'draft',
|
||||||
|
}, depends=['state'])
|
||||||
|
|
||||||
|
@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._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')
|
||||||
|
))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def default_agended(self):
|
||||||
|
return False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def default_sale_date(cls):
|
||||||
|
return datetime.today().date()
|
||||||
|
|
||||||
|
@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 _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):
|
||||||
|
Shipment = super(Sale, self)._get_shipment_sale(Shipment, key)
|
||||||
|
Shipment.sale_type = self.sale_type
|
||||||
|
Shipment.service_maintenance_initial = \
|
||||||
|
True if self.sale_type != 'equipments' else False
|
||||||
|
|
||||||
|
return Shipment
|
||||||
|
|
||||||
|
@ 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 is not 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):
|
||||||
|
today = datetime.today().date()
|
||||||
|
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('shipment_state', 'none')
|
||||||
|
default.setdefault('sale_date', today)
|
||||||
|
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):
|
||||||
|
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' and not sale.agended:
|
||||||
|
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.id
|
||||||
|
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(sales)
|
||||||
|
with transaction.set_context(
|
||||||
|
queue_scheduled_at=config.sale_process_after,
|
||||||
|
queue_batch=context.get('queue_batch', True)):
|
||||||
|
cls.__queue__.process(sales)
|
||||||
|
|
||||||
|
|
||||||
class SaleLine(metaclass=PoolMeta):
|
class SaleLine(metaclass=PoolMeta):
|
||||||
'SaleLine'
|
'SaleLine'
|
||||||
__name__ = 'sale.line'
|
__name__ = 'sale.line'
|
||||||
|
|
||||||
address_equipment = fields.Many2One('party.address', "Direccion")
|
product_equipment = fields.Boolean("Product Equipment")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ModelView.button
|
def __setup__(cls):
|
||||||
def process(cls, sales):
|
super(SaleLine, cls).__setup__()
|
||||||
states = {'confirmed', 'processing', 'done'}
|
cls.product.domain.append(
|
||||||
sales = [s for s in sales if s.state in states]
|
If(Eval('_parent_sale.sale_type') == 'maintenance',
|
||||||
cls.lock(sales)
|
[('type', '=', 'service'),
|
||||||
cls._process_invoice(sales)
|
('maintenance_activity', '=', True)], []))
|
||||||
cls._process_shipment(sales)
|
cls.product.domain.append(
|
||||||
cls._process_invoice_shipment_states(sales)
|
If(Eval('_parent_sale.sale_type') == 'replaces',
|
||||||
cls._process_state(sales)
|
[('replacement', '=', True)], []))
|
||||||
|
|
||||||
|
@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.unit = 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()
|
||||||
|
|||||||
81
sale.xml
81
sale.xml
@@ -1,9 +1,80 @@
|
|||||||
<?xml version="1.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. -->
|
<!--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>
|
<tryton>
|
||||||
<record model="ir.ui.view" id="sale_line_view_form">
|
<data>
|
||||||
<field name="model">sale.line</field>
|
<record model="ir.ui.view" id="sale_view_tree">
|
||||||
<field name="inherit" ref="sale.sale_line_view_form"/>
|
<field name="model">sale.sale</field>
|
||||||
<field name="name">sale_line_form</field>
|
<field name="inherit" ref="sale.sale_view_tree"/>
|
||||||
|
<field name="name">sale_tree</field>
|
||||||
</record>
|
</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> -->
|
||||||
|
</data>
|
||||||
</tryton>
|
</tryton>
|
||||||
|
|||||||
17
setup.py
17
setup.py
@@ -69,20 +69,20 @@ if minor_version % 2:
|
|||||||
|
|
||||||
setup(name=name,
|
setup(name=name,
|
||||||
version=version,
|
version=version,
|
||||||
description='Modúlo a medida para optica',
|
description='',
|
||||||
long_description=read('README.rst'),
|
long_description=read('README.rst'),
|
||||||
author='OneTeam',
|
author='Tryton',
|
||||||
author_email='info@onecluster.org',
|
author_email='bugs@tryton.org',
|
||||||
url='http://www.tryton.org/',
|
url='http://www.tryton.org/',
|
||||||
keywords='',
|
keywords='',
|
||||||
package_dir={'trytond.modules.smart_vision': '.'},
|
package_dir={'trytond.modules.optical_equipment': '.'},
|
||||||
packages=(
|
packages=(
|
||||||
['trytond.modules.smart_vision']
|
['trytond.modules.optical_equipment']
|
||||||
+ ['trytond.modules.smart_vision.%s' % p
|
+ ['trytond.modules.optical_equipment.%s' % p
|
||||||
for p in find_packages()]
|
for p in find_packages()]
|
||||||
),
|
),
|
||||||
package_data={
|
package_data={
|
||||||
'trytond.modules.smart_vision': (info.get('xml', [])
|
'trytond.modules.optical_equipment': (info.get('xml', [])
|
||||||
+ ['tryton.cfg', 'view/*.xml', 'locale/*.po', '*.fodt',
|
+ ['tryton.cfg', 'view/*.xml', 'locale/*.po', '*.fodt',
|
||||||
'icons/*.svg', 'tests/*.rst']),
|
'icons/*.svg', 'tests/*.rst']),
|
||||||
},
|
},
|
||||||
@@ -115,6 +115,7 @@ setup(name=name,
|
|||||||
'Natural Language :: Slovenian',
|
'Natural Language :: Slovenian',
|
||||||
'Natural Language :: Spanish',
|
'Natural Language :: Spanish',
|
||||||
'Natural Language :: Turkish',
|
'Natural Language :: Turkish',
|
||||||
|
'Natural Language :: Ukrainian',
|
||||||
'Operating System :: OS Independent',
|
'Operating System :: OS Independent',
|
||||||
'Programming Language :: Python :: 3',
|
'Programming Language :: Python :: 3',
|
||||||
'Programming Language :: Python :: 3.7',
|
'Programming Language :: Python :: 3.7',
|
||||||
@@ -134,6 +135,6 @@ setup(name=name,
|
|||||||
zip_safe=False,
|
zip_safe=False,
|
||||||
entry_points="""
|
entry_points="""
|
||||||
[trytond.modules]
|
[trytond.modules]
|
||||||
smart_vision = trytond.modules.smart_vision
|
optical_equipment = trytond.modules.optical_equipment
|
||||||
""", # noqa: E501
|
""", # noqa: E501
|
||||||
)
|
)
|
||||||
|
|||||||
12
shipment.xml
Normal file
12
shipment.xml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?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>
|
||||||
|
<data>
|
||||||
|
<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>
|
||||||
|
</data>
|
||||||
|
</tryton>
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
from trytond.pool import PoolMeta
|
|
||||||
from trytond.model import ModelSQL, ModelView, fields
|
|
||||||
|
|
||||||
class Subscription(metaclass=PoolMeta):
|
|
||||||
__name__ = 'sale.subscription'
|
|
||||||
|
|
||||||
equipments = fields.Many2Many('sale.subscription-optical_equipment.equipment', 'subscription', 'equipment', "Equipments")
|
|
||||||
|
|
||||||
class SubscriptionEquipment(ModelSQL):
|
|
||||||
'Optical Equipment - Subscription'
|
|
||||||
__name__ = 'sale.subscription-optical_equipment.equipment'
|
|
||||||
|
|
||||||
subscription = fields.Many2One('sale.subscription', 'Subscription', select=True)
|
|
||||||
equipment = fields.Many2One('optical_equipment.equipment', 'Equipment', select=True)
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<!--This file file is part of Tryton. The COPYRIGHT file at the top level of this repository contains the full copyright notices and license terms. -->
|
|
||||||
<tryton>
|
|
||||||
<record model="ir.ui.view" id="subscription_view_form">
|
|
||||||
<field name="model">sale.subscription</field>
|
|
||||||
<field name="inherit" ref="sale_subscription.subscription_view_form"/>
|
|
||||||
<field name="name">subscription_form</field>
|
|
||||||
</record>
|
|
||||||
</tryton>
|
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
|
# this repository contains the full copyright notices and license terms.
|
||||||
|
|||||||
41863
tests/files/database.dump
Normal file
41863
tests/files/database.dump
Normal file
File diff suppressed because one or more lines are too long
BIN
tests/files/signature.png
Normal file
BIN
tests/files/signature.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.2 KiB |
495
tests/scenario_optical_equipment.rst
Normal file
495
tests/scenario_optical_equipment.rst
Normal file
@@ -0,0 +1,495 @@
|
|||||||
|
===========================
|
||||||
|
Optical Equipment Scenario
|
||||||
|
===========================
|
||||||
|
Imports::
|
||||||
|
>>> from proteus import Model, Wizard
|
||||||
|
>>> from trytond.tests.tools import activate_modules, set_user
|
||||||
|
>>> from datetime import date, timedelta, datetime
|
||||||
|
>>> import xml.etree.ElementTree as ET
|
||||||
|
>>> from trytond.modules.company.tests.tools import create_company, get_company
|
||||||
|
>>> from trytond.modules.account.tests.tools import (create_chart, create_fiscalyear, create_tax, get_accounts)
|
||||||
|
>>> from trytond.modules.account_invoice.tests.tools import (create_payment_term, set_fiscalyear_invoice_sequences)
|
||||||
|
>>> from decimal import Decimal
|
||||||
|
>>> import datetime
|
||||||
|
>>> today = datetime.date.today()
|
||||||
|
>>> from trytond.tools import file_open
|
||||||
|
|
||||||
|
Activate modules::
|
||||||
|
>>> config = activate_modules('optical_equipment')
|
||||||
|
|
||||||
|
Create company::
|
||||||
|
>>> _ = create_company()
|
||||||
|
>>> company = get_company()
|
||||||
|
|
||||||
|
Create user admin::
|
||||||
|
>>> Group = Model.get("res.group")
|
||||||
|
>>> User = Model.get("res.user")
|
||||||
|
>>> user = User(config.user)
|
||||||
|
>>> user.login = "admin"
|
||||||
|
>>> user.save()
|
||||||
|
>>> group, = Group().find(["name", "=", "Administration"])
|
||||||
|
>>> group
|
||||||
|
proteus.Model.get('res.group')(1)
|
||||||
|
|
||||||
|
>>> group_equipment, = Group().find(["name", "=", "Equipment Administration"])
|
||||||
|
>>> group_equipment
|
||||||
|
proteus.Model.get('res.group')(18)
|
||||||
|
|
||||||
|
>>> group.users.append(user)
|
||||||
|
>>> group.save()
|
||||||
|
>>> group_equipment.users
|
||||||
|
[proteus.Model.get('res.user')(1)]
|
||||||
|
|
||||||
|
Set employee::
|
||||||
|
>>> User = Model.get('res.user')
|
||||||
|
>>> Party = Model.get('party.party')
|
||||||
|
>>> Employee = Model.get('company.employee')
|
||||||
|
>>> employee_party = Party(name="Employee")
|
||||||
|
>>> employee_party.save()
|
||||||
|
>>> employee = Employee(party=employee_party)
|
||||||
|
>>> employee.save()
|
||||||
|
>>> user = User(config.user)
|
||||||
|
>>> user.employees.append(employee)
|
||||||
|
>>> user.employee = employee
|
||||||
|
>>> user.save()
|
||||||
|
>>> set_user(user.id)
|
||||||
|
|
||||||
|
Create fiscal year::
|
||||||
|
>>> fiscalyear = set_fiscalyear_invoice_sequences(create_fiscalyear(company))
|
||||||
|
>>> fiscalyear.click('create_period')
|
||||||
|
|
||||||
|
Create chart of accounts::
|
||||||
|
>>> _ = create_chart(company)
|
||||||
|
>>> accounts = get_accounts(company)
|
||||||
|
>>> accounts
|
||||||
|
{'receivable': proteus.Model.get('account.account')(5), 'payable': proteus.Model.get('account.account')(4), 'revenue': proteus.Model.get('account.account')(6), 'expense': proteus.Model.get('account.account')(3), 'cash': proteus.Model.get('account.account')(2), 'tax': proteus.Model.get('account.account')(7)}
|
||||||
|
|
||||||
|
>>> revenue = accounts['revenue']
|
||||||
|
>>> expense = accounts['expense']
|
||||||
|
>>> cash = accounts['cash']
|
||||||
|
|
||||||
|
>>> Journal = Model.get('account.journal')
|
||||||
|
>>> PaymentMethod = Model.get('account.invoice.payment.method')
|
||||||
|
>>> cash_journal, = Journal.find([('type', '=', 'cash')])
|
||||||
|
>>> cash_journal.save()
|
||||||
|
>>> payment_method = PaymentMethod()
|
||||||
|
>>> payment_method.name = 'Cash'
|
||||||
|
>>> payment_method.journal = cash_journal
|
||||||
|
>>> payment_method.credit_account = cash
|
||||||
|
>>> payment_method.debit_account = cash
|
||||||
|
>>> payment_method.save()
|
||||||
|
|
||||||
|
Create tax::
|
||||||
|
>>> tax = create_tax(Decimal('.10'))
|
||||||
|
>>> tax.save()
|
||||||
|
|
||||||
|
Create configuration equipment::
|
||||||
|
>>> Config = Model.get("optical_equipment.configuration")
|
||||||
|
>>> UOM = Model.get("product.uom")
|
||||||
|
>>> celsius = UOM.find([("name", "=", "Celsius")])
|
||||||
|
>>> celsius
|
||||||
|
[proteus.Model.get('product.uom')(39)]
|
||||||
|
|
||||||
|
>>> moisture = UOM.find([("name", "=", "Relative Humedity")])
|
||||||
|
>>> moisture
|
||||||
|
[proteus.Model.get('product.uom')(42)]
|
||||||
|
|
||||||
|
>>> config = Config().find([])[0]
|
||||||
|
>>> equipment_sequence, = Model.get("ir.sequence").find(["name", "=", "Equipment"])
|
||||||
|
>>> equipment_sequence
|
||||||
|
proteus.Model.get('ir.sequence')(14)
|
||||||
|
|
||||||
|
>>> config.technician_responsible = employee
|
||||||
|
>>> with file_open("optical_equipment/tests/files/signature.png", "rb") as signature:
|
||||||
|
... config.technician_signature = signature.read()
|
||||||
|
>>> config.invima = "RH-202309-02409"
|
||||||
|
>>> config.equipment_sequence = equipment_sequence
|
||||||
|
>>> maintenance_sequence, = Model.get("ir.sequence").find(["name", "=", "Maintenance"])
|
||||||
|
>>> maintenance_sequence
|
||||||
|
proteus.Model.get('ir.sequence')(15)
|
||||||
|
|
||||||
|
|
||||||
|
>>> config.maintenance_sequence = maintenance_sequence
|
||||||
|
>>> agended_sequence, = Model.get("ir.sequence").find(["name", "=", "Agended"])
|
||||||
|
>>> agended_sequence
|
||||||
|
proteus.Model.get('ir.sequence')(13)
|
||||||
|
|
||||||
|
>>> config.agended_sequence = agended_sequence
|
||||||
|
|
||||||
|
>>> contract_sequence, = Model.get("ir.sequence").find(["name", "=", "Contract"])
|
||||||
|
>>> contract_sequence
|
||||||
|
proteus.Model.get('ir.sequence')(12)
|
||||||
|
>>> config.contract_sequence = contract_sequence
|
||||||
|
|
||||||
|
>>> sale_quote_number, = Model.get("ir.sequence").find(["name", "=", "Sale Quote"])
|
||||||
|
>>> sale_quote_number
|
||||||
|
proteus.Model.get('ir.sequence')(16)
|
||||||
|
>>> config.sale_quote_number = sale_quote_number
|
||||||
|
|
||||||
|
>>> config.temperature_min = 19
|
||||||
|
>>> config.temperature_max = 21
|
||||||
|
>>> config.temperature_uom = celsius[0]
|
||||||
|
|
||||||
|
>>> config.moisture_min = 43
|
||||||
|
>>> config.moisture_max = 45
|
||||||
|
>>> config.moisture_uom = moisture[0]
|
||||||
|
>>> config.save()
|
||||||
|
|
||||||
|
Create supplier::
|
||||||
|
>>> Party = Model.get('party.party')
|
||||||
|
>>> supplier = Party(name='Supplier')
|
||||||
|
>>> supplier.save()
|
||||||
|
|
||||||
|
|
||||||
|
Create customer type optica::
|
||||||
|
>>> customer_optica = Party(name='Customer optica', customer_type='optica')
|
||||||
|
>>> customer_optica.save()
|
||||||
|
>>> customer_optica.customer_type
|
||||||
|
'optica'
|
||||||
|
|
||||||
|
|
||||||
|
Create customer type ips::
|
||||||
|
>>> customer_ips = Party(name='Customer ips', customer_type='ips')
|
||||||
|
>>> customer_ips.save()
|
||||||
|
>>> customer_ips.customer_type
|
||||||
|
'ips'
|
||||||
|
|
||||||
|
Creaate contact optica::
|
||||||
|
>>> local_phone = customer_optica.contact_mechanisms.new()
|
||||||
|
>>> local_phone.type = 'phone'
|
||||||
|
>>> local_phone.value = '666666666'
|
||||||
|
>>> local_phone.value
|
||||||
|
'666666666'
|
||||||
|
|
||||||
|
Creaate contact ips::
|
||||||
|
>>> local_phone = customer_ips.contact_mechanisms.new()
|
||||||
|
>>> local_phone.type = 'phone'
|
||||||
|
>>> local_phone.value = '666666666'
|
||||||
|
>>> local_phone.value
|
||||||
|
'666666666'
|
||||||
|
|
||||||
|
|
||||||
|
Create account categories::
|
||||||
|
>>> ProductCategory = Model.get('product.category')
|
||||||
|
>>> optical_equitment_category = ProductCategory(name="Optical Equipment")
|
||||||
|
>>> optical_equitment_category.accounting = True
|
||||||
|
>>> optical_equitment_category.account_expense = expense
|
||||||
|
>>> optical_equitment_category.account_revenue = revenue
|
||||||
|
>>> children_1 = optical_equitment_category.childs.new(name="Optical Mobiliario")
|
||||||
|
>>> optical_equitment_category.save()
|
||||||
|
>>> len(optical_equitment_category.childs)
|
||||||
|
1
|
||||||
|
|
||||||
|
Create taxes::
|
||||||
|
>>> optical_equitment_category_tax, = optical_equitment_category.duplicate()
|
||||||
|
>>> optical_equitment_category_tax.customer_taxes.append(tax)
|
||||||
|
>>> optical_equitment_category_tax.save()
|
||||||
|
|
||||||
|
Create mark, model and reference category::
|
||||||
|
>>> mark_category = ProductCategory(name="ADLER")
|
||||||
|
>>> mark_category.save()
|
||||||
|
>>> model_category = ProductCategory(name="ADLER_01", parent=mark_category)
|
||||||
|
>>> model_category.save()
|
||||||
|
>>> reference_category = ProductCategory(name="ADLER_01", parent=model_category)
|
||||||
|
>>> reference_category.save()
|
||||||
|
|
||||||
|
>>> mark_category.childs
|
||||||
|
[proteus.Model.get('product.category')(6)]
|
||||||
|
|
||||||
|
Create product optical equipment::
|
||||||
|
>>> ProductUom = Model.get('product.uom')
|
||||||
|
>>> unit, = ProductUom.find([('name', '=', 'Unit')])
|
||||||
|
>>> ProductTemplate = Model.get('product.template')
|
||||||
|
>>> template = ProductTemplate()
|
||||||
|
>>> template.name = 'UNIDAD REFRACCION ESTANDAR'
|
||||||
|
>>> template.default_uom = unit
|
||||||
|
>>> template.type = 'goods'
|
||||||
|
>>> template.salable = True
|
||||||
|
>>> template.purchasable = True
|
||||||
|
>>> template.equipment = True
|
||||||
|
>>> template.list_price = Decimal('10')
|
||||||
|
>>> template.account_category = optical_equitment_category_tax
|
||||||
|
>>> template.maintenance_required = True
|
||||||
|
|
||||||
|
Mark Maintenance Activities::
|
||||||
|
>>> template.initial_operation = True
|
||||||
|
>>> template.check_equipment = True
|
||||||
|
>>> template.check_electric_system = True
|
||||||
|
>>> template.clean_int_ext = True
|
||||||
|
>>> template.preventive_activities = "Se verificaron las condiciones ambientales, se verificó estado físico del equipo, se verificó funcionamiento, se verificó tomas eléctricas y conexiones, se verificó el estado de los pulsadores, se verificó que el motor de la silla suba y baje, se realizó limpieza general, se lubricaron partes que lo requieren, se confirmó nuevamente funcionamiento."
|
||||||
|
|
||||||
|
Mark Calibration Required::
|
||||||
|
>>> template.calibration = True
|
||||||
|
>>> template.uncertainy_pattern = 0.1
|
||||||
|
>>> template.k_pattern = '-5.00'
|
||||||
|
>>> UsePattern = Model.get('optical_equipment.use_pattern')
|
||||||
|
>>> schematic_eye, = UsePattern.find([('name_pattern', '=', 'Schematic Eye')])
|
||||||
|
>>> template.use_pattern = schematic_eye
|
||||||
|
>>> k_pattern = template.k_pattern_list.new(pattern=-5)
|
||||||
|
>>> k_pattern.save()
|
||||||
|
>>> template.MEP = 0.1
|
||||||
|
>>> template.Usubi = 200
|
||||||
|
>>> template.resolution_type = 'digital'
|
||||||
|
>>> template.d_resolution = 0.25
|
||||||
|
>>> template.equipment_type = 'mobiliario_optico'
|
||||||
|
>>> template.biomedical_class = 'diagnostico'
|
||||||
|
>>> template.main_tecnology = 'electronico'
|
||||||
|
>>> template.mark_category = mark_category
|
||||||
|
>>> template.model_category = model_category
|
||||||
|
>>> template.use = 'medico'
|
||||||
|
>>> template.reference_category = reference_category
|
||||||
|
>>> template.save()
|
||||||
|
>>> len(template.k_pattern_list)
|
||||||
|
1
|
||||||
|
>>> product, = template.products
|
||||||
|
>>> product.name
|
||||||
|
'UNIDAD REFRACCION ESTANDAR'
|
||||||
|
|
||||||
|
Create Product Maintenance Service::
|
||||||
|
>>> maintenanceServiceProduct = ProductTemplate()
|
||||||
|
>>> maintenanceServiceProduct.name = 'Mantenimiento Correctivo'
|
||||||
|
>>> maintenanceServiceProduct.maintenance_activity = True
|
||||||
|
>>> maintenanceServiceProduct.default_uom = unit
|
||||||
|
>>> maintenanceServiceProduct.type = 'service'
|
||||||
|
>>> maintenanceServiceProduct.salable = True
|
||||||
|
>>> maintenanceServiceProduct.purchasable = True
|
||||||
|
>>> maintenanceServiceProduct.list_price = Decimal('10')
|
||||||
|
>>> maintenanceServiceProduct.account_category = optical_equitment_category_tax
|
||||||
|
>>> maintenanceServiceProduct.save()
|
||||||
|
>>> product1, = maintenanceServiceProduct.products
|
||||||
|
>>> product1.name
|
||||||
|
'Mantenimiento Correctivo'
|
||||||
|
|
||||||
|
|
||||||
|
Create payment term::
|
||||||
|
>>> payment_term = create_payment_term()
|
||||||
|
>>> payment_term.save()
|
||||||
|
|
||||||
|
Purchase 5 products:
|
||||||
|
>>> Purchase = Model.get('purchase.purchase')
|
||||||
|
>>> PurchaseLine = Model.get('purchase.line')
|
||||||
|
>>> purchase = Purchase()
|
||||||
|
>>> purchase.party = supplier
|
||||||
|
>>> purchase.payment_term = payment_term
|
||||||
|
>>> purchase.invoice_method = 'order'
|
||||||
|
>>> purchase_line = PurchaseLine()
|
||||||
|
>>> purchase.lines.append(purchase_line)
|
||||||
|
>>> purchase_line.product = product
|
||||||
|
>>> purchase_line.quantity = 2.0
|
||||||
|
>>> purchase_line.product_equipment
|
||||||
|
True
|
||||||
|
>>> purchase_line.unit_price = Decimal('6182237.0000')
|
||||||
|
>>> purchase_line.health_register = 'COL123evergreen'
|
||||||
|
>>> purchase.click('quote')
|
||||||
|
>>> purchase.click('confirm')
|
||||||
|
>>> purchase.click('create_equipments')
|
||||||
|
>>> Equipment = Model.get('optical_equipment.equipment')
|
||||||
|
>>> equipments = Equipment.find()
|
||||||
|
>>> equipments
|
||||||
|
[proteus.Model.get('optical_equipment.equipment')(1), proteus.Model.get('optical_equipment.equipment')(2)]
|
||||||
|
>>> len(equipments)
|
||||||
|
2
|
||||||
|
>>> purchase.equipment_create
|
||||||
|
1
|
||||||
|
|
||||||
|
Finalize the purchase inventory movements::
|
||||||
|
>>> for move in purchase.moves:
|
||||||
|
... move.click('do')
|
||||||
|
|
||||||
|
Registred equipment without serial::
|
||||||
|
>>> equipment_1 = equipments[0]
|
||||||
|
>>> equipment_2 = equipments[1]
|
||||||
|
>>> equipment_1.click('registred') # doctest: +IGNORE_EXCEPTION_DETAIL
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
UserError: ...
|
||||||
|
>>> equipment_1.serial = "2020DM-0021167"
|
||||||
|
>>> equipment_1.click('registred')
|
||||||
|
>>> equipment_2.serial = "2020DM-002119"
|
||||||
|
>>> equipment_2.click('registred')
|
||||||
|
|
||||||
|
First sale::
|
||||||
|
>>> Sale = Model.get('sale.sale')
|
||||||
|
>>> SaleLine = Model.get('sale.line')
|
||||||
|
>>> sale = Sale()
|
||||||
|
>>> sale.party = customer_optica
|
||||||
|
>>> sale.contact = local_phone
|
||||||
|
>>> sale.description = 'El producto se debe entregar el fin de semana'
|
||||||
|
>>> sale.sale_date = today
|
||||||
|
>>> sale.sale_type = 'equipments'
|
||||||
|
>>> sale.payment_term = payment_term
|
||||||
|
>>> sale.invoice_method = 'order'
|
||||||
|
>>> sale_line = SaleLine()
|
||||||
|
>>> sale.lines.append(sale_line)
|
||||||
|
>>> sale_line.product = product
|
||||||
|
>>> sale_line.quantity = 2.0
|
||||||
|
>>> sale_line = SaleLine()
|
||||||
|
>>> sale.lines.append(sale_line)
|
||||||
|
>>> sale_line.type = 'comment'
|
||||||
|
>>> sale_line.description = 'Comment'
|
||||||
|
>>> sale_line = SaleLine()
|
||||||
|
>>> sale.lines.append(sale_line)
|
||||||
|
>>> sale_line.product = product
|
||||||
|
>>> sale_line.quantity = 3.0
|
||||||
|
>>> sale.click('quote')
|
||||||
|
>>> SaleConfirmDate = sale.click('confirm')
|
||||||
|
>>> SaleConfirmDate.form.sale_date == today
|
||||||
|
True
|
||||||
|
>>> SaleConfirmDate.execute('confirm_date')
|
||||||
|
>>> sale.state
|
||||||
|
'processing'
|
||||||
|
>>> sale.shipments
|
||||||
|
[proteus.Model.get('stock.shipment.out')(1)]
|
||||||
|
|
||||||
|
Duplicate Sale::
|
||||||
|
>>> sale.duplicate()
|
||||||
|
[proteus.Model.get('sale.sale')(2)]
|
||||||
|
|
||||||
|
Return Sale::
|
||||||
|
>>> SaleReturn = Wizard('sale.return_sale', [sale])
|
||||||
|
>>> SaleReturn.execute('return_')
|
||||||
|
|
||||||
|
Verify that the sale state could be returned to the draft state::
|
||||||
|
>>> sale.click("draft")
|
||||||
|
>>> sale.state
|
||||||
|
'draft'
|
||||||
|
>>> sale_line = SaleLine()
|
||||||
|
>>> sale.lines.append(sale_line)
|
||||||
|
>>> sale_line.product = product
|
||||||
|
>>> sale_line.quantity = 2.0
|
||||||
|
>>> sale.click('quote')
|
||||||
|
>>> SaleConfirmDate = sale.click('confirm')
|
||||||
|
>>> SaleConfirmDate.execute('confirm_date')
|
||||||
|
>>> sale.shipments
|
||||||
|
[proteus.Model.get('stock.shipment.out')(1), proteus.Model.get('stock.shipment.out')(2)]
|
||||||
|
|
||||||
|
Verify that the shipment cannot be assigned if the shipment lines do not have equipment::
|
||||||
|
>>> shipment_one = sale.shipments[0]
|
||||||
|
>>> shipment_one.click('pick') # doctest: +IGNORE_EXCEPTION_DETAIL
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
ValidationError: ...
|
||||||
|
|
||||||
|
Restrict assignment when the shipment has no serialized items::
|
||||||
|
>>> shipment_one = sale.shipments[0]
|
||||||
|
>>> line_one = shipment_one.inventory_moves[0]
|
||||||
|
>>> line_one.equipment = equipment_1
|
||||||
|
>>> line_one.equipment_serial
|
||||||
|
'2020DM-0021167'
|
||||||
|
>>> line_two = shipment_one.inventory_moves[1]
|
||||||
|
>>> line_two.equipment = equipment_2
|
||||||
|
>>> line_two.equipment_serial
|
||||||
|
'2020DM-002119'
|
||||||
|
>>> shipment_one.click('assign_try')
|
||||||
|
>>> shipment_one.click('pick')
|
||||||
|
>>> shipment_one.click('pack')
|
||||||
|
>>> shipment_one.click('done')
|
||||||
|
|
||||||
|
Create a new Maintenance Service::
|
||||||
|
>>> shipment_one.click('maintenance_initial')
|
||||||
|
>>> MantenanceServices = Model.get("optical_equipment_maintenance.service")
|
||||||
|
>>> mantenanceServices, = MantenanceServices.find()
|
||||||
|
>>> mantenanceServices
|
||||||
|
proteus.Model.get('optical_equipment_maintenance.service')(1)
|
||||||
|
>>> mantenanceServices.state
|
||||||
|
'draft'
|
||||||
|
|
||||||
|
>>> MaintenanceLines = Model.get("optical_equipment.maintenance")
|
||||||
|
>>> maintenanceLines = MaintenanceLines.find()
|
||||||
|
>>> maintenanceLines
|
||||||
|
[proteus.Model.get('optical_equipment.maintenance')(1), proteus.Model.get('optical_equipment.maintenance')(2)]
|
||||||
|
>>> maintenanceLines[0].state
|
||||||
|
'draft'
|
||||||
|
|
||||||
|
>>> maintenance_1 = maintenanceLines[0]
|
||||||
|
>>> maintenance_2 = maintenanceLines[1]
|
||||||
|
>>> maintenance_1.equipment.state
|
||||||
|
'uncontrated'
|
||||||
|
>>> maintenance_1.equipment.propietary == customer_optica
|
||||||
|
True
|
||||||
|
>>> maintenance_1.equipment.propietary_address.street
|
||||||
|
|
||||||
|
>>> maintenance_2.equipment.state
|
||||||
|
'uncontrated'
|
||||||
|
>>> maintenance_2.equipment.propietary == customer_optica
|
||||||
|
True
|
||||||
|
>>> maintenance_2.equipment.propietary_address.street
|
||||||
|
|
||||||
|
Assing schedule to maintenance service::
|
||||||
|
>>> AssingSchedule = Wizard('optical_equipment_maintenance.assing_agended', [mantenanceServices])
|
||||||
|
>>> AssingSchedule.form.estimated_agended = datetime.datetime.now()
|
||||||
|
>>> AssingSchedule.form.technical = employee
|
||||||
|
>>> AssingSchedule.execute('assing_agended')
|
||||||
|
|
||||||
|
>>> mantenanceServices.state
|
||||||
|
'agended'
|
||||||
|
|
||||||
|
>>> mantenanceServices.click('in_progress')
|
||||||
|
>>> mantenanceServices.state
|
||||||
|
'in_progress'
|
||||||
|
|
||||||
|
>>> mantenanceServices.lines
|
||||||
|
[proteus.Model.get('optical_equipment.maintenance')(1), proteus.Model.get('optical_equipment.maintenance')(2)]
|
||||||
|
|
||||||
|
Calibrate Maintenance Lines::
|
||||||
|
>>> mantenance_lines = mantenanceServices.lines
|
||||||
|
>>> mantenance_line_one = mantenance_lines[0]
|
||||||
|
>>> mantenance_line_two = mantenance_lines[1]
|
||||||
|
>>> mantenance_line_one.click('samples')
|
||||||
|
>>> len(mantenance_line_one.lines_calibration)
|
||||||
|
5
|
||||||
|
>>> mantenance_line_one.click('calibrate')
|
||||||
|
>>> mantenance_line_one.calibration_total
|
||||||
|
[proteus.Model.get('optical_equipment.maintenance.calibration')(1)]
|
||||||
|
>>> len(mantenance_line_one.graph_calibration)
|
||||||
|
14857
|
||||||
|
|
||||||
|
>>> mantenance_line_one.click('finished')
|
||||||
|
>>> mantenance_line_one.state
|
||||||
|
'finished'
|
||||||
|
|
||||||
|
Finished Maintenance Service::
|
||||||
|
>>> mantenanceServices.click('finished') # doctest: +IGNORE_EXCEPTION_DETAIL
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
ValidationError: ...
|
||||||
|
|
||||||
|
>>> mantenance_line_two.click('samples')
|
||||||
|
>>> len(mantenance_line_two.lines_calibration)
|
||||||
|
5
|
||||||
|
>>> mantenance_line_two.click('calibrate')
|
||||||
|
>>> mantenance_line_two.calibration_total
|
||||||
|
[proteus.Model.get('optical_equipment.maintenance.calibration')(2)]
|
||||||
|
>>> len(mantenance_line_two.graph_calibration)
|
||||||
|
14857
|
||||||
|
>>> mantenance_line_two.click('finished')
|
||||||
|
>>> mantenanceServices.click('finished')
|
||||||
|
>>> mantenanceServices.state
|
||||||
|
'finished'
|
||||||
|
|
||||||
|
Create a New Contract::
|
||||||
|
|
||||||
|
|
||||||
|
Sale Maintenance Service::
|
||||||
|
>>> sale2 = Sale()
|
||||||
|
>>> sale2.party = customer_optica
|
||||||
|
>>> sale2.contact = local_phone
|
||||||
|
>>> sale2.description = 'El producto se debe entregar el fin de semana'
|
||||||
|
>>> sale2.sale_date = today
|
||||||
|
>>> sale2.sale_type = 'maintenance'
|
||||||
|
>>> sale2.maintenance_type = 'corrective'
|
||||||
|
>>> sale2.payment_term = payment_term
|
||||||
|
>>> sale2.invoice_method = 'order'
|
||||||
|
>>> sale_line = SaleLine()
|
||||||
|
>>> sale2.lines.append(sale_line)
|
||||||
|
>>> sale_line.product = product1
|
||||||
|
>>> sale_line.quantity = 1.0
|
||||||
|
>>> sale2.click('quote')
|
||||||
|
>>> SaleConfirmDate = sale2.click('confirm')
|
||||||
|
>>> SaleConfirmDate.form.sale_date == today
|
||||||
|
True
|
||||||
|
>>> SaleConfirmDate.execute('confirm_date')
|
||||||
|
>>> sale2.state
|
||||||
|
'processing'
|
||||||
|
>>> sale2.shipments
|
||||||
|
[]
|
||||||
@@ -2,9 +2,9 @@
|
|||||||
from trytond.tests.test_tryton import ModuleTestCase
|
from trytond.tests.test_tryton import ModuleTestCase
|
||||||
|
|
||||||
|
|
||||||
class SmartVisionTestCase(ModuleTestCase):
|
class OpticalEquipmentTestCase(ModuleTestCase):
|
||||||
"Test Smart Vision module"
|
"Test Optical Equipment module"
|
||||||
module = 'smart_vision'
|
module = 'optical_equipment'
|
||||||
|
|
||||||
|
|
||||||
del ModuleTestCase
|
del ModuleTestCase
|
||||||
|
|||||||
8
tests/test_scenario.py
Normal file
8
tests/test_scenario.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# 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.tests.test_tryton import load_doc_tests
|
||||||
|
|
||||||
|
|
||||||
|
def load_tests(*args, **kwargs):
|
||||||
|
return load_doc_tests(__name__, __file__, *args, **kwargs)
|
||||||
4
tox.ini
4
tox.ini
@@ -4,8 +4,8 @@ envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
|
|||||||
[testenv]
|
[testenv]
|
||||||
extras = test
|
extras = test
|
||||||
commands =
|
commands =
|
||||||
coverage run --include=.*/smart_vision/* -m unittest discover -s tests
|
coverage run --include=./**/optical_equipment/* -m unittest discover -s tests
|
||||||
coverage report --include=.*/smart_vision/* --omit=*/tests/*
|
coverage report --include=./**/optical_equipment/* --omit=*/tests/*
|
||||||
deps =
|
deps =
|
||||||
coverage
|
coverage
|
||||||
postgresql: psycopg2 >= 2.7.0
|
postgresql: psycopg2 >= 2.7.0
|
||||||
|
|||||||
31
tryton.cfg
31
tryton.cfg
@@ -1,22 +1,31 @@
|
|||||||
[tryton]
|
[tryton]
|
||||||
version=6.0
|
version=7.0.0
|
||||||
depends:
|
depends:
|
||||||
ir
|
ir
|
||||||
party
|
|
||||||
company
|
company
|
||||||
|
account_product
|
||||||
|
party
|
||||||
product
|
product
|
||||||
|
product_attribute
|
||||||
|
product_image
|
||||||
product_measurements
|
product_measurements
|
||||||
purchase
|
purchase
|
||||||
sale
|
sale
|
||||||
stock
|
|
||||||
country
|
|
||||||
sale_subscription
|
|
||||||
xml:
|
xml:
|
||||||
party.xml
|
company.xml
|
||||||
product.xml
|
|
||||||
measurements.xml
|
|
||||||
equipment.xml
|
equipment.xml
|
||||||
sale.xml
|
calibration.xml
|
||||||
purchase.xml
|
contract.xml
|
||||||
|
diary.xml
|
||||||
|
agended.xml
|
||||||
|
configuration.xml
|
||||||
|
maintenance.xml
|
||||||
|
move.xml
|
||||||
|
party.xml
|
||||||
uom.xml
|
uom.xml
|
||||||
subscription.xml
|
product.xml
|
||||||
|
purchase.xml
|
||||||
|
sale.xml
|
||||||
|
balance_sale_party.xml
|
||||||
|
shipment.xml
|
||||||
|
messages.xml
|
||||||
46
uom.xml
46
uom.xml
@@ -27,13 +27,55 @@ this repository contains the full copyright notices and license terms. -->
|
|||||||
<field name="rounding" eval="1."/>
|
<field name="rounding" eval="1."/>
|
||||||
<field name="digits" eval="0"/>
|
<field name="digits" eval="0"/>
|
||||||
</record>
|
</record>
|
||||||
<record model="product.uom.category" id="uom_cat_frecuency">
|
<record model="product.uom.category" id="uom_cat_frequency">
|
||||||
<field name="name">Frequency</field>
|
<field name="name">Frequency</field>
|
||||||
</record>
|
</record>
|
||||||
<record model="product.uom" id="uom_electrical2">
|
<record model="product.uom" id="uom_electrical2">
|
||||||
<field name="name">Hertz</field>
|
<field name="name">Hertz</field>
|
||||||
<field name="symbol">Hrz</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="rate" eval="1."/>
|
||||||
<field name="factor" eval="1."/>
|
<field name="factor" eval="1."/>
|
||||||
<field name="rounding" eval="1."/>
|
<field name="rounding" eval="1."/>
|
||||||
|
|||||||
14
view/address_form.xml
Normal file
14
view/address_form.xml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
|
this repository contains the full copyright notices and license terms. -->
|
||||||
|
<data>
|
||||||
|
<xpath expr="/form/field[@name='party_name']" position="after">
|
||||||
|
<newline/>
|
||||||
|
<label name="party_related"/>
|
||||||
|
<field name="party_related"/>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="/form/group[@id='checkboxes']/field[@name='active']" position="after">
|
||||||
|
<label name="campus"/>
|
||||||
|
<field name="campus"/>
|
||||||
|
</xpath>
|
||||||
|
</data>
|
||||||
8
view/address_tree.xml
Normal file
8
view/address_tree.xml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
|
this repository contains the full copyright notices and license terms. -->
|
||||||
|
<data>
|
||||||
|
<!-- <xpath expr="//field[@name='street']" position="replace"> -->
|
||||||
|
<!-- <field name="street" expand="1"/> -->
|
||||||
|
<!-- </xpath> -->
|
||||||
|
</data>
|
||||||
16
view/assing_agended_form.xml
Normal file
16
view/assing_agended_form.xml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level
|
||||||
|
this repository contains the full copyright notices and license terms. -->
|
||||||
|
<form>
|
||||||
|
<label name="maintenance_service"/>
|
||||||
|
<field name="maintenance_service" colspan="3"/>
|
||||||
|
<newline/>
|
||||||
|
<label name="estimated_agended"/>
|
||||||
|
<field name="estimated_agended" colspan="3" widget="date"/>
|
||||||
|
<newline/>
|
||||||
|
<label name="estimated_agended" string="Hora:"/>
|
||||||
|
<field name="estimated_agended" colspan="3" widget="time"/>
|
||||||
|
<newline/>
|
||||||
|
<label name="technical"/>
|
||||||
|
<field name="technical" colspan="3"/>
|
||||||
|
</form>
|
||||||
35
view/calibration_total_form.xml
Normal file
35
view/calibration_total_form.xml
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
|
this repository contains the full copyright notices and license terms. -->
|
||||||
|
<form>
|
||||||
|
<label name="diopter"/>
|
||||||
|
<field name="diopter"/>
|
||||||
|
<label name="dev_std"/>
|
||||||
|
<field name="dev_std"/>
|
||||||
|
<label name="uncertain_type_A"/>
|
||||||
|
<field name="uncertain_type_A"/>
|
||||||
|
<label name="uncertain_pattern"/>
|
||||||
|
<field name="uncertain_pattern"/>
|
||||||
|
<label name="k_c_calibration"/>
|
||||||
|
<field name="k_c_calibration"/>
|
||||||
|
<label name="uncertain_U_b1"/>
|
||||||
|
<field name="uncertain_U_b1"/>
|
||||||
|
<label name="d_resolution"/>
|
||||||
|
<field name="d_resolution"/>
|
||||||
|
<label name="uncertain_U_b2_dig"/>
|
||||||
|
<field name="uncertain_U_b2_dig"/>
|
||||||
|
<label name="uncertain_U_b2_ana"/>
|
||||||
|
<field name="uncertain_U_b2_ana"/>
|
||||||
|
<label name="uncertain_combinated"/>
|
||||||
|
<field name="uncertain_combinated"/>
|
||||||
|
<label name="uncertain_eff"/>
|
||||||
|
<field name="uncertain_eff"/>
|
||||||
|
<label name="t_student"/>
|
||||||
|
<field name="t_student"/>
|
||||||
|
<label name="uncertain_expanded"/>
|
||||||
|
<field name="uncertain_expanded"/>
|
||||||
|
<label name="graph_dates"/>
|
||||||
|
<field name="graph_dates"/>
|
||||||
|
<label name="state"/>
|
||||||
|
<field name="state"/>
|
||||||
|
</form>
|
||||||
19
view/calibration_total_tree.xml
Normal file
19
view/calibration_total_tree.xml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
|
this repository contains the full copyright notices and license terms. -->
|
||||||
|
<tree>
|
||||||
|
<field name="diopter" expand="1"/>
|
||||||
|
<field name="dev_std" expand="1"/>
|
||||||
|
<field name="uncertain_type_A" expand="1"/>
|
||||||
|
<field name="uncertain_pattern" expand="1"/>
|
||||||
|
<field name="k_c_calibration" expand="1"/>
|
||||||
|
<field name="uncertain_U_b1" expand="1"/>
|
||||||
|
<field name="d_resolution" expand="1"/>
|
||||||
|
<field name="uncertain_U_b2_dig" expand="1"/>
|
||||||
|
<field name="uncertain_U_b2_ana" expand="1"/>
|
||||||
|
<field name="uncertain_combinated" expand="1"/>
|
||||||
|
<field name="uncertain_eff" expand="1"/>
|
||||||
|
<field name="t_student" expand="1"/>
|
||||||
|
<field name="uncertain_expanded" expand="1"/>
|
||||||
|
<field name="state" expand="1"/>
|
||||||
|
</tree>
|
||||||
35
view/calibratoin_total_form.xml
Normal file
35
view/calibratoin_total_form.xml
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
|
this repository contains the full copyright notices and license terms. -->
|
||||||
|
<form>
|
||||||
|
<label name="diopter"/>
|
||||||
|
<field name="diopter"/>
|
||||||
|
<label name="dev_std"/>
|
||||||
|
<field name="dev_std"/>
|
||||||
|
<label name="uncertain_type_A"/>
|
||||||
|
<field name="uncertain_type_A"/>
|
||||||
|
<label name="uncertain_pattern"/>
|
||||||
|
<field name="uncertain_pattern"/>
|
||||||
|
<label name="k_c_calibration"/>
|
||||||
|
<field name="k_c_calibration"/>
|
||||||
|
<label name="uncertain_U_b1"/>
|
||||||
|
<field name="uncertain_U_b1"/>
|
||||||
|
<label name="d_resolution"/>
|
||||||
|
<field name="d_resolution"/>
|
||||||
|
<label name="uncertain_U_b2_dig"/>
|
||||||
|
<field name="uncertain_U_b2_dig"/>
|
||||||
|
<label name="uncertain_U_b2_ana"/>
|
||||||
|
<field name="uncertain_U_b2_ana"/>
|
||||||
|
<label name="uncertain_combinated"/>
|
||||||
|
<field name="uncertain_combinated"/>
|
||||||
|
<label name="uncertain_eff"/>
|
||||||
|
<field name="uncertain_eff"/>
|
||||||
|
<label name="t_student"/>
|
||||||
|
<field name="t_student"/>
|
||||||
|
<label name="uncertain_expanded"/>
|
||||||
|
<field name="uncertain_expanded"/>
|
||||||
|
<label name="graph_dates"/>
|
||||||
|
<field name="graph_dates"/>
|
||||||
|
<label name="state"/>
|
||||||
|
<field name="state"/>
|
||||||
|
</form>
|
||||||
16
view/change_propietary_form.xml
Normal file
16
view/change_propietary_form.xml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level
|
||||||
|
this repository contains the full copyright notices and license terms. -->
|
||||||
|
<form>
|
||||||
|
<label name="old_propietary"/>
|
||||||
|
<field name="old_propietary"/>
|
||||||
|
<newline/>
|
||||||
|
<field name="equipments" colspan="3"/>
|
||||||
|
<newline/>
|
||||||
|
<label name="new_propietary"/>
|
||||||
|
<field name="new_propietary" colspan="3"/>
|
||||||
|
<label name="new_address"/>
|
||||||
|
<field name="new_address" colspan="3"/>
|
||||||
|
<label name="change_date"/>
|
||||||
|
<field name="change_date" colspan="3"/>
|
||||||
|
</form>
|
||||||
16
view/change_propietary_maintenance_form.xml
Normal file
16
view/change_propietary_maintenance_form.xml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level
|
||||||
|
this repository contains the full copyright notices and license terms. -->
|
||||||
|
<form>
|
||||||
|
<label name="old_propietary"/>
|
||||||
|
<field name="old_propietary"/>
|
||||||
|
<newline/>
|
||||||
|
<field name="maintenance_service" colspan="3"/>
|
||||||
|
<newline/>
|
||||||
|
<label name="new_propietary"/>
|
||||||
|
<field name="new_propietary" colspan="3"/>
|
||||||
|
<label name="new_address"/>
|
||||||
|
<field name="new_address" colspan="3"/>
|
||||||
|
<label name="change_date"/>
|
||||||
|
<field name="change_date" colspan="3"/>
|
||||||
|
</form>
|
||||||
54
view/configuration_form.xml
Normal file
54
view/configuration_form.xml
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
<?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="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/>
|
||||||
|
|
||||||
|
<separator id="technician_responsible" string="Technician Responsible" colspan="4"/>
|
||||||
|
<label name="technician_responsible"/>
|
||||||
|
<field name="technician_responsible"/>
|
||||||
|
|
||||||
|
<label name="invima"/>
|
||||||
|
<field name="invima"/>
|
||||||
|
|
||||||
|
<label name="technician_signature"/>
|
||||||
|
<field name="technician_signature"/>
|
||||||
|
</form>
|
||||||
7
view/confirm_sale_date_form.xml
Normal file
7
view/confirm_sale_date_form.xml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
|
this repository contains the full copyright notices and license terms. -->
|
||||||
|
<form>
|
||||||
|
<label name="sale_date"/>
|
||||||
|
<field name="sale_date"/>
|
||||||
|
</form>
|
||||||
51
view/contract_form.xml
Normal file
51
view/contract_form.xml
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<?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="current_equipments"/>
|
||||||
|
</page>
|
||||||
|
<page string="History Equipments" id="history_equipments">
|
||||||
|
<field name="history_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="6" id="button">
|
||||||
|
<button name="draft"/>
|
||||||
|
<button name="closed"/>
|
||||||
|
<button name="cancelled"/>
|
||||||
|
<button name="running"/>
|
||||||
|
</group>
|
||||||
|
</form>
|
||||||
12
view/contract_list.xml
Normal file
12
view/contract_list.xml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
|
this repository contains the full copyright notices and license terms. -->
|
||||||
|
<tree>
|
||||||
|
<field name="number"/>
|
||||||
|
<field name="party"/>
|
||||||
|
<field name="reference"/>
|
||||||
|
<field name="description"/>
|
||||||
|
<field name="start_date"/>
|
||||||
|
<field name="end_date"/>
|
||||||
|
<field name="state"/>
|
||||||
|
</tree>
|
||||||
23
view/create_contract_form.xml
Normal file
23
view/create_contract_form.xml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level
|
||||||
|
this repository contains the full copyright notices and license terms. -->
|
||||||
|
<form>
|
||||||
|
<group id="create_contract" col="2">
|
||||||
|
<label name="party"/>
|
||||||
|
<field name="party"/>
|
||||||
|
<newline/>
|
||||||
|
<label name="invoice_address"/>
|
||||||
|
<field name="invoice_address"/>
|
||||||
|
<newline/>
|
||||||
|
<label name="contact"/>
|
||||||
|
<field name="contact"/>
|
||||||
|
<newline/>
|
||||||
|
<label name="start_date"/>
|
||||||
|
<field name="start_date"/>
|
||||||
|
<label name="end_date"/>
|
||||||
|
<field name="end_date"/>
|
||||||
|
<newline/>
|
||||||
|
<label name="unit_price"/>
|
||||||
|
<field name="unit_price"/>
|
||||||
|
</group>
|
||||||
|
</form>
|
||||||
24
view/diary_form.xml
Normal file
24
view/diary_form.xml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
|
this repository contains the full copyright notices and license terms. -->
|
||||||
|
<form col="6">
|
||||||
|
<label name="maintenance_service"/>
|
||||||
|
<field name="maintenance_service"/>
|
||||||
|
<label name="code"/>
|
||||||
|
<field name="code"/>
|
||||||
|
<newline/>
|
||||||
|
<notebook colspan="6">
|
||||||
|
<page string="Dates" id="dates_agended">
|
||||||
|
<label name="date_expected"/>
|
||||||
|
<field name="date_expected"/>
|
||||||
|
<label name="date_estimated"/>
|
||||||
|
<field name="date_estimated"/>
|
||||||
|
<label name="date_end"/>
|
||||||
|
<field name="date_end"/>
|
||||||
|
</page>
|
||||||
|
</notebook>
|
||||||
|
<label name="technical"/>
|
||||||
|
<field name="technical"/>
|
||||||
|
<label name="state"/>
|
||||||
|
<field name="state"/>
|
||||||
|
</form>
|
||||||
12
view/diary_tree.xml
Normal file
12
view/diary_tree.xml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
|
this repository contains the full copyright notices and license terms. -->
|
||||||
|
<tree>
|
||||||
|
<field name="code"/>
|
||||||
|
<field name="date_expected" widget="date"/>
|
||||||
|
<field name="date_expected" string="time" widget="time"/>
|
||||||
|
<field name="date_estimated" widget="date"/>
|
||||||
|
<field name="date_end" widget="date"/>
|
||||||
|
<field name="maintenance_service"/>
|
||||||
|
<field name="technical"/>
|
||||||
|
</tree>
|
||||||
10
view/employee_form.xml
Normal file
10
view/employee_form.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
|
this repository contains the full copyright notices and license terms. -->
|
||||||
|
<data>
|
||||||
|
<xpath expr="//field[@name='supervisor']" position="after">
|
||||||
|
<label name="invima"/>
|
||||||
|
<field name="invima"/>
|
||||||
|
<newline/>
|
||||||
|
</xpath>
|
||||||
|
</data>
|
||||||
80
view/equipment_form.xml
Normal file
80
view/equipment_form.xml
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
|
this repository contains the full copyright notices and license terms. -->
|
||||||
|
<form col="6">
|
||||||
|
<label name="code"/>
|
||||||
|
<field name="code"/>
|
||||||
|
<label name="company"/>
|
||||||
|
<field name="company"/>
|
||||||
|
<label name="active"/>
|
||||||
|
<field name="active"/>
|
||||||
|
<newline/>
|
||||||
|
<label name="propietary"/>
|
||||||
|
<field name="propietary"/>
|
||||||
|
<label name="propietary_address"/>
|
||||||
|
<field name="propietary_address"/>
|
||||||
|
<notebook colspan="6">
|
||||||
|
<page string="General" id="general_equipment">
|
||||||
|
<label name="location"/>
|
||||||
|
<field name="location"/>
|
||||||
|
<label name="product"/>
|
||||||
|
<field name="product"/>
|
||||||
|
<label name="equipment_type"/>
|
||||||
|
<field name="equipment_type"/>
|
||||||
|
<label name="use"/>
|
||||||
|
<field name="use"/>
|
||||||
|
<label name="biomedical_class"/>
|
||||||
|
<field name="biomedical_class"/>
|
||||||
|
<label name="calibration"/>
|
||||||
|
<field name="calibration"/>
|
||||||
|
<newline/>
|
||||||
|
<label name="mark_category"/>
|
||||||
|
<field name="mark_category"/>
|
||||||
|
<label name="model_category"/>
|
||||||
|
<field name="model_category"/>
|
||||||
|
<label name="reference_category"/>
|
||||||
|
<field name="reference_category"/>
|
||||||
|
<label name="refurbish"/>
|
||||||
|
<field name="refurbish"/>
|
||||||
|
<label name="software_version"/>
|
||||||
|
<field name="software_version"/>
|
||||||
|
<label name="useful_life"/>
|
||||||
|
<field name="useful_life"/>
|
||||||
|
<label name="warranty"/>
|
||||||
|
<field name="warranty"/>
|
||||||
|
<newline/>
|
||||||
|
<label name="maintenance_frequency"/>
|
||||||
|
<field name="maintenance_frequency"/>
|
||||||
|
<label name="serial"/>
|
||||||
|
<field name="serial"/>
|
||||||
|
<label name="health_register"/>
|
||||||
|
<field name="health_register"/>
|
||||||
|
<label name="origin_country"/>
|
||||||
|
<field name="origin_country"/>
|
||||||
|
</page>
|
||||||
|
<page string="Contracts" id="contract_equipment">
|
||||||
|
<field name="contract_history"/>
|
||||||
|
</page>
|
||||||
|
<page string="Maintenances" id="maintenances_equipment">
|
||||||
|
<field name="maintenance_history"/>
|
||||||
|
</page>
|
||||||
|
<page string="Propietarys" id="propietarys_equipment">
|
||||||
|
<field name="propietarys"/>
|
||||||
|
</page>
|
||||||
|
<page string="Origins" id="origins_equipment">
|
||||||
|
<separator id="purchase_origin" string="Purchase Origin" colspan="4"/>
|
||||||
|
<field name="purchase_origin"/>
|
||||||
|
<newline/>
|
||||||
|
<separator id="sale_destination" string="Sale Destination" colspan="4"/>
|
||||||
|
<field name="sale_destination"/>
|
||||||
|
<separator id="shipment_destination" string="Shipment Destination" colspan="4"/>
|
||||||
|
<field name="shipment_destination"/>
|
||||||
|
</page>
|
||||||
|
</notebook>
|
||||||
|
<group col="2" colspan="2" id="button">
|
||||||
|
<button name="draft"/>
|
||||||
|
<button name="registred"/>
|
||||||
|
</group>
|
||||||
|
<label name="state"/>
|
||||||
|
<field name="state"/>
|
||||||
|
</form>
|
||||||
11
view/equipment_serial_tree.xml
Normal file
11
view/equipment_serial_tree.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
|
this repository contains the full copyright notices and license terms.-->
|
||||||
|
<tree editable="1">
|
||||||
|
<field name="code"/>
|
||||||
|
<field name="purchase_origin"/>
|
||||||
|
<field name="propietary"/>
|
||||||
|
<field name="product"/>
|
||||||
|
<field name="serial" expand="1"/>
|
||||||
|
<button name="registred"/>
|
||||||
|
</tree>
|
||||||
13
view/equipment_tree.xml
Normal file
13
view/equipment_tree.xml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
|
this repository contains the full copyright notices and license terms.-->
|
||||||
|
<tree>
|
||||||
|
<field name="code"/>
|
||||||
|
<field name="location"/>
|
||||||
|
<field name="propietary"/>
|
||||||
|
<field name="propietary_address"/>
|
||||||
|
<field name="product" expand="1"/>
|
||||||
|
<field name="mark_category"/>
|
||||||
|
<field name="model_category"/>
|
||||||
|
<field name="serial"/>
|
||||||
|
</tree>
|
||||||
7
view/maintenance_activity_form.xml
Normal file
7
view/maintenance_activity_form.xml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
|
this repository contains the full copyright notices and license terms. -->
|
||||||
|
<form>
|
||||||
|
<label name="product"/>
|
||||||
|
<field name="product"/>
|
||||||
|
</form>
|
||||||
6
view/maintenance_activity_tree.xml
Normal file
6
view/maintenance_activity_tree.xml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
|
this repository contains the full copyright notices and license terms. -->
|
||||||
|
<tree>
|
||||||
|
<field name="product"/>
|
||||||
|
</tree>
|
||||||
9
view/maintenance_calibracion_tree.xml
Normal file
9
view/maintenance_calibracion_tree.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
|
this repository contains the full copyright notices and license terms.-->
|
||||||
|
<tree>
|
||||||
|
<field name="value_patterns" expand="1"/>
|
||||||
|
<field name="value_equipment" expand="1"/>
|
||||||
|
<field name="mistake" expand="1"/>
|
||||||
|
<field name="mistake_rate" expand="1"/>
|
||||||
|
</tree>
|
||||||
9
view/maintenance_calibration_tree.xml
Normal file
9
view/maintenance_calibration_tree.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
|
this repository contains the full copyright notices and license terms.-->
|
||||||
|
<tree>
|
||||||
|
<field name="value_patterns" expand="1"/>
|
||||||
|
<field name="value_equipment" expand="1"/>
|
||||||
|
<field name="mistake" expand="1"/>
|
||||||
|
<field name="mistake_rate" expand="1"/>
|
||||||
|
</tree>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user