405 lines
14 KiB
Python
405 lines
14 KiB
Python
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
|